2011-01-14 41 views
17

Tôi có một số Form. Tôi muốn bao gồm một trường ẩn trả về một mô hình. Tôi sẽ đặt giá trị của nó trong khung nhìn; Tôi chỉ cần nó được đăng dọc theo trang tiếp theo.Các hình thức Django: Trường mô hình ẩn?

Tôi phải sử dụng trường nào trong lớp biểu mẫu?

Trả lời

26

Trường ẩn trả về mô hình? Vậy một ID cá thể mô hình?

Các widget forms.HiddenInput nên làm các trick, cho dù trên một sân FK hoặc CharField bạn đặt một ID mô hình ví dụ trong.

class MyForm(forms.Form): 
    hidden_2 = forms.CharField(widget=forms.HiddenInput()) 
    hidden_css = forms.CharField(widget=forms.MostWidgets(attrs={'style': 'display:none;'})) 

Tôi cho rằng cách nhanh nhất để làm việc này là

class MyForm(forms.Form): 
    model_instance = forms.ModelChoiceField(queryset=MyModel.objects.all(), widget=forms.HiddenInput()) 

form = MyForm({'model_instance': '1'}) 
form.cleaned_data['model_instance'] 

Nhưng tôi không thích ý tưởng cung cấp MyModel.objects.all() nếu bạn định chỉ định một mục anyways.

Dường như để tránh hành vi đó, bạn phải ghi đè biểu mẫu __init__ với số nhỏ hơn QuerySet.

Tôi nghĩ rằng tôi thích theo cách cũ thời:

class MyForm(forms.Form): 
    model_instance = forms.CharField(widget=forms.HiddenInput()) 

    def clean_model_instance(self): 
     data = self.cleaned_data['model_instance'] 
     if not data: 
      raise forms.ValidationError() 
     try: 
      instance = MyModel.objects.get(id=data) 
     except MyModel.DoesNotExist: 
      raise forms.ValidationError() 
     return instance 
+0

Đừng nghĩ 'ForeignKey' là một lĩnh vực hình thức có giá trị ... đó là một lĩnh vực mô hình. Tôi muốn nó trả về một thể hiện mô hình chứ không phải là một số nguyên (khi tôi lấy nó sau này với 'form.cleaned_data ['field']') – mpen

+0

Haha, bạn hoàn toàn đúng .. xin lỗi về điều đó :) –

+0

forms.MostWidgets ? có nghĩa là hầu hết các widget có sẵn? – fanny

2

Cách tiếp cận trong câu trả lời Yuji của sử dụng một phương pháp clean_model_instance về hình thức mà là tốt nếu bạn chỉ bao giờ làm điều này một lần trong cơ sở mã của bạn. Nếu bạn làm điều đó thường xuyên hơn, thì bạn có thể hưởng lợi từ việc triển khai trường mô hình tùy chỉnh.

Đây là mã tôi có:

from django import forms 

class ModelField(forms.Field): 

    Model = None 

    def prepare_value(self, value): 
     """Inject entities' id value into the form's html data""" 
     if isinstance(value, self.Model): 
      return value.id 
     return value 

    def to_python(self, value): 
     """More or less stolen from ModelChoiceField.to_python""" 

     if value in self.empty_values: 
      return None 

     try: 
      value = self.Model.objects.get(id=value) 
     except (ValueError, self.Model.DoesNotExist): 
      raise forms.ValidationError('%s does not exist' 
             % self.Model.__class__.__name__.capitalize()) 

     return value 

Nếu bạn sử dụng như một lớp cơ sở và sau đó chuyên nó với các mô hình riêng của bạn sau đó nó trở thành một hữu ích dựa. Ví dụ:

# In app/fields.py 
from .models import CustomModel 

class CustomModelField(ModelField): 

    Model = CustomModel 

Sau đó, bạn có thể ghép nối đó với bất cứ phụ tùng bạn cần vào thời điểm đó:

# in app/forms.py 
class MyForm(forms.Form): 

    hidden_custom_model_field = CustomModelField(widget=forms.HiddenInput()) 

    other_widget_custom_model_field = CustomModelField(widget=MyCustomWidget()) 
Các vấn đề liên quan