2011-01-14 22 views
17

मुझे Form मिल गया है। मैं एक छिपे हुए फ़ील्ड को शामिल करना चाहता हूं जो एक मॉडल लौटाता है। मैं इसे देखने में मूल्य निर्धारित करूंगा; मुझे बस अगले पृष्ठ पर पोस्ट करने की आवश्यकता है।Django फॉर्म: छुपा मॉडल फ़ील्ड?

मुझे फॉर्म क्लास में किस क्षेत्र का उपयोग करना चाहिए?

उत्तर

26

एक छुपा क्षेत्र जो मॉडल लौटाता है? तो एक मॉडल उदाहरण आईडी?

forms.HiddenInput विजेट है कि क्या एक FK क्षेत्र या CharField पर आप में एक मॉडल उदाहरण आईडी डाल चाल करना चाहिए,।

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

मैं इस काम के प्राप्त करने के लिए सबसे तेज़ तरीका लगता है

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'] 
है

लेकिन अगर आप एक आइटम को वैसे भी निर्दिष्ट करने जा रहे हैं तो मुझे MyModel.objects.all() की आपूर्ति करने का विचार पसंद नहीं है।

ऐसा लगता है कि उस व्यवहार से बचने के लिए, आपको को छोटे QuerySet के साथ ओवरराइड करना होगा।

मुझे लगता है कि मैं पुराने जमाने तरीका पसंद करते हैं:

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

मत सोचो 'ForeignKey' एक वैध प्रपत्र क्षेत्र है ... यह एक मॉडल क्षेत्र है। मैं इसके बजाय एक पूर्णांक की बजाय एक मॉडल उदाहरण लौटा दूंगा (जब मैं इसे बाद में 'form.cleaned_data [' field '] ' – mpen

+0

हाहा के साथ पुनर्प्राप्त करता हूं, तो आप बिल्कुल सही हैं .. इसके बारे में खेद है :) –

+0

रूप। मॉस्टविड्ज ? अर्थात् अधिकांश उपलब्ध विजेट्स? – fanny

2

युजी के जवाब में दृष्टिकोण रूप है जो ठीक है अगर आप केवल कभी अपने कोड बेस में एक बार इस कार्य कर रहे हैं पर एक clean_model_instance विधि का उपयोग करता। यदि आप इसे अधिक बार करते हैं, तो आपको कस्टम मॉडल फ़ील्ड को लागू करने से लाभ हो सकता है।

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 

आप उपयोग करते हैं कि एक आधार वर्ग के रूप में और फिर अपने स्वयं के मॉडल के साथ विशेषज्ञ तो यह एक उपयोगी आधारित हो जाता है:

इस कोड को मेरे पास है। उदाहरण के लिए:

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

class CustomModelField(ModelField): 

    Model = CustomModel 

तो फिर तुम जोड़ी कर सकते हैं कि जो कुछ भी विजेट के साथ आप समय की जरूरत है:

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

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

    other_widget_custom_model_field = CustomModelField(widget=MyCustomWidget()) 
संबंधित मुद्दे