2011-09-26 11 views
14

मेरे पास यह फॉर्म फ़ील्ड है:मैं HTML आवश्यक विशेषता दिखाने के लिए Django रूपों को कैसे प्राप्त करूं?

email = forms.EmailField(
    required=True, 
    max_length=100, 
) 

इसमें आवश्यक विशेषता है, लेकिन HTML में यह HTML विशेषता required नहीं जोड़ रहा है। वास्तव में यह email का उपयोग फ़ील्ड प्रकार के रूप में भी नहीं कर रहा है, यह text का उपयोग कर रहा है ... हालांकि ऐसा लगता है कि अधिकतम_लेथेंथ ठीक है।

वास्तविक:

<input id="id_email" type="text" name="email" maxlength="100"> 

अपेक्षित:

<input id="id_email" type="email" name="email" maxlength="100" required="true"> 

मैं Django को HTML रूपों में सही विशेषताओं का उपयोग करने के लिए कैसे प्राप्त कर सकता हूं?

उत्तर

6

Monkeypatching विजेट अपने सबसे अच्छे शर्त है मॉडलफॉर्म मैं बस उपयोग करता हूं:

class NewForm(HTML5RequiredMixin, forms.Form): 
    ... 
+3

हे धन्यवाद मुझे !! –

+4

क्या मैं सुझाव दे सकता हूं कि आप पढ़ने के लिए अगर कथन बदलते हैं: 'अगर self.is_required और टाइप (स्वयं) में नहीं है (AdminFileWidget, HiddenInput, FileInput) और "__prefix__" attrs ["name"] में नहीं:' इससे रोका जाएगा ब्राउज़र को 'आवश्यक = "सत्य जोड़ने से' 'जब किसी ऑब्जेक्ट में पहले से फ़ाइल संलग्न होती है, साथ ही स्टैक्डइनलाइन और टैबबेडइनलाइन व्यवस्थापक सामग्री के लिए बनाए गए छिपे हुए" नकली "फ़ील्ड को छोड़ दें। –

16

Django फॉर्म तत्व <input /> के खिलाफ लिखे गए हैं क्योंकि यह HTML 4 में मौजूद है, जहां type="text" ई-मेल पते के लिए सही विकल्प था। required="true" भी नहीं था।

यदि आप कस्टम HTML विशेषताओं चाहते हैं, तो आपको attrsविजेट पर कीवर्ड तर्क की आवश्यकता है। यह कुछ इस तरह दिखेगा:

email = forms.EmailField(
    max_length=100, 
    required=True, 
    widget=forms.TextInput(attrs={ 'required': 'true' }), 
) 

आप विगेट्स here बारे में अधिक दस्तावेज़ की जाँच कर सकते हैं। attrs की चर्चा उस पृष्ठ के निचले भाग के पास है।

type="email" के संबंध में, आप इसे अपने attrs शब्दकोश में भेज सकते हैं और Django बुद्धिमानी से इसके डिफ़ॉल्ट को ओवरराइड कर पाएगा। यदि आपको नतीजा नहीं मिलता है, तो आपका मार्ग forms.TextInput को उप-वर्ग करना है और फिर इसे widget कीवर्ड तर्क में पास करना है।

from django.forms.widgets import Widget 
from django.contrib.admin.widgets import AdminFileWidget 
from django.forms import HiddenInput, FileInput 

old_build_attrs = Widget.build_attrs 

def build_attrs(self, extra_attrs=None, **kwargs): 
    attrs = old_build_attrs(self, extra_attrs, **kwargs) 

    # if required, and it's not a file widget since those can have files 
    # attached without seeming filled-in to the browser, and skip hidden "mock" 
    # fileds created for StackedInline and TabbedInline admin stuff 
    if (self.is_required 
      and type(self) not in (AdminFileWidget, HiddenInput, FileInput) 
      and "__prefix__" not in attrs.get("name", "")): 
     attrs['required'] = 'required' 

    return attrs 

Widget.build_attrs = build_attrs 
+0

क्या बंदरगाह फॉर्म क्लास बेस क्लास पैच करने का कोई तरीका है? ऐसा लगता है कि आवश्यक गुण दो बार निर्दिष्ट करना बहुत ही मुश्किल है। मुझे लगता है कि –

+0

मुझे लगता है। यह 'django.forms.BaseForm' है। –

7

का मेल डैनियल और डैनियल जवाब, मैं आमतौर पर मेरी रूपों के लिए इस mixin का उपयोग करें::

from django.contrib.admin.widgets import AdminFileWidget 
from django.forms.widgets import HiddenInput, FileInput 


class HTML5RequiredMixin(object): 

    def __init__(self, *args, **kwargs): 
     super(HTML5RequiredMixin, self).__init__(*args, **kwargs) 
     for field in self.fields: 
      if (self.fields[field].required and 
       type(self.fields[field].widget) not in 
        (AdminFileWidget, HiddenInput, FileInput) and 
       '__prefix__' not in self.fields[field].widget.attrs): 

        self.fields[field].widget.attrs['required'] = 'required' 
        if self.fields[field].label: 
         self.fields[field].label += ' *' 

तो जब मैं एक नया रूप बनाने के लिए या

+0

मेरे मामले में, मुझे 'फॉर्म ऑब्जेक्ट में कोई विशेषता नहीं है' फ़ील्ड 'क्योंकि पाइथन बाएं से दाएं' __init__ 'का मूल्यांकन करता है और HTML ऑब्जेक्ट के समय HTML ऑब्जेक्ट' __init__ 'कॉल के समय फॉर्म ऑब्जेक्ट उपलब्ध नहीं था। इस तरह की कक्षा घोषणा के आदेश को बदलने के बाद और न्यूफॉर्म के __init__ का हिस्सा यह काम करता है। 'क्लास न्यूफॉर्म (फॉर्म.फॉर्म, एचटीएमएल 5RequiredMixin)', फिर न्यूफॉर्म का __init__, 'HTML5RequiredMixin .__ init__' पर कॉल करें – Hobaak

5

फ़िल्टर का उपयोग करके टेम्पलेट-केवल समाधान भी है। मैं django-widget-tweaks:

{% load widget_tweaks %} 

{{ form.email|attr:'required:true' }} 

यह आसान था।

4

जैसा कि आपने महसूस किया है, True पर अपने फ़ील्ड आवश्यक विशेषता को सेट करना केवल बैकएंड सत्यापन के लिए है, जैसा कि Django documentation में बताया गया है।

email.widget.attrs["required"] = "required" 

यदि आपको वास्तव में सुंदर, सूखी कोड लिखना चाहते हैं, आप एक आधार रूप वर्ग जो गतिशील रूप से लग रहा है बनाना चाहिए:

क्या आप वास्तव में चाहते हैं क्षेत्र के Widget करने के लिए एक आवश्यक विशेषता जोड़ने के लिए है अपने सभी आवश्यक फ़ील्ड के लिए और आप के लिए अपने विजेट आवश्यक विशेषता को संशोधित करता है (यदि आप इसे नाम कर सकते हैं जो कुछ भी आप चाहते हैं, लेकिन "BaseForm" उपयुक्त लगता है):

from django.forms import ModelForm 

class BaseForm(ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(BaseForm, self).__init__(*args, **kwargs) 
     for bound_field in self: 
      if hasattr(bound_field, "field") and bound_field.field.required: 
       bound_field.field.widget.attrs["required"] = "required" 

और फिर है अपने सभी फार्म वस्तुओं से उतर:

class UserForm(BaseForm): 
    class Meta: 
     model = User 
     fields = [] 

    first_name = forms.CharField(required=True) 
    last_name = forms.CharField(required=True) 
    email = forms.EmailField(required=True, max_length=100) 
3

Django 1.10 के बाद से, यह अंतर्निहित है।

release notes से:

आवश्यक प्रपत्र फ़ील्ड्स अब आवश्यक HTML विशेषता है। अक्षम करने के लिए गलत बनाने के लिए नया Form.use_required_attribute विशेषता सेट करें।

+0

बहुत बहुत धन्यवाद, मुझे इस विशेषता को काफी लंबे समय तक सेट करने में समस्याएं आ रही हैं। – quapka

संबंधित मुद्दे

 संबंधित मुद्दे