Django प्रपत्र में css वर्ग को परिभाषित करें


192

मान लें कि मेरे पास एक फॉर्म है

class SampleClass(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    django_hacker = forms.BooleanField(required=False)

क्या मेरे लिए प्रत्येक क्षेत्र पर सीएसएस कक्षाओं को परिभाषित करने का एक तरीका है जैसे मैं अपने रेंडर किए गए पृष्ठ में कक्षा के आधार पर jQuery का उपयोग कर सकता हूं?

मैं उम्मीद कर रहा था कि फॉर्म को मैन्युअली नहीं बनाना पड़ेगा।


9
वाह, सब लोग इसे वोट देते हैं? docs.djangoproject.com/en/dev/ref/forms/widgets/…
Skylar Saveland

10
@skyl मैं इसे एक संकेत के रूप में लेता हूं कि django डॉक्स में इसे खोजना आसान नहीं है। मैंने ब्राउज किया और कई Google खोज भी की और यह नहीं पाया, इसलिए मैं इस प्रश्न के लिए खुश हूं और यह मेरा उत्थान है।
निल्स

मुझे पता है कि यह एक पुराना धागा है, लेकिन Django के फॉर्म फ़ील्ड में अब एक id_fieldname वर्ग है।
ratsimihah

1
मौजूदा फ़ील्ड कक्षाओं का सम्मान करते हुए एक टेम्पलेट के अंदर फॉर्म फ़ील्ड के लिए कक्षाओं को कैसे परिभाषित करें, इस उत्तर को देखें
dimyG

जवाबों:


182

अभी तक एक और समाधान है कि अजगर कोड में बदलाव की आवश्यकता नहीं है और इसलिए डिजाइनरों और एकतरफा प्रस्तुति परिवर्तनों के लिए बेहतर है: django- विजेट-ट्विक्स । आशा है किसी को यह उपयोगी लगेगा।


61
केवल समझदार समाधान, मुझे कहना पड़ेगा। धन्यवाद!। पायथन कोड, और विशेष रूप से फॉर्म की परिभाषा में, स्टाइल के लिए सामान रखने के लिए अंतिम स्थान है - ये निश्चित रूप से टेम्पलेट्स से संबंधित हैं।
बोरिस चेरवेंकोव

5
यह एक महान पुस्तकालय है! यह शर्म की बात है कि यह जवाब नीचे दफन है।
क्रिस लैकेस

1
डिजाइनरों के लिए बढ़िया है! :-)
hobbes3

1
अति उत्कृष्ट! मैंने इन सामानों को करने के लिए कुछ फिल्टर विकसित किए थे, लेकिन यह परियोजना बहुत अधिक शक्तिशाली है। धन्यवाद!
msbrogli

1
वास्तव में यह जिन्जा 2 के लिए भी काम करता है। :-) मैंने सुरक्षित फ़िल्टर के क्रम को बदल दिया और बृहदान्त्र के बजाय {{mys.email। Add_class ("css_class_1 css_class_2") के बजाय कोष्ठक जोड़ा। सुरक्षित} यह लिखने के लिए धन्यवाद यह Django का हिस्सा होना चाहिए।
डेविड डेगन

92

मेरे ही सवाल का जवाब दिया। आह

http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs

मुझे नहीं पता था कि इसे विजेट कंस्ट्रक्टर में पारित किया गया था।


2
इसका मतलब यह है कि यह ModelForm वर्ग के साथ इस्तेमाल नहीं किया जा सकता है?
xster

2
नहीं, आपको केवल मॉडल रूप में फ़ील्ड को स्पष्ट रूप से परिभाषित करने की आवश्यकता होगी ताकि आप विजेट को परिभाषित कर सकें। या फार्म क्षेत्र के साथ घुलने से बचने के लिए नीचे सूचीबद्ध समाधान का उपयोग करें।
टॉम

78

कक्षा में फ़ील्ड घोषित करने के बाद विजेट्स में वर्ग परिभाषाएँ जोड़ने के लिए एक और उपाय है।

def __init__(self, *args, **kwargs):
    super(SampleClass, self).__init__(*args, **kwargs)
    self.fields['name'].widget.attrs['class'] = 'my_class'

4
ModelForms के लिए, यह अक्सर बेहतर होता है क्योंकि आपको उपयोग किए जाने वाले डिफ़ॉल्ट फ़ॉर्म फ़ील्ड के बारे में जानकारी होने की आवश्यकता नहीं होती है, और आप रनटाइम स्थितियों के आधार पर विभिन्न वर्गों को गतिशील रूप से सेट कर सकते हैं। मेटा कोडिंग हैक्स की तुलना में क्लीनर ...
डैनियल नाब

1
यह मानता है कि आप एक फॉर्म में हर क्षेत्र के लिए एक इनपुट चाहते हैं, जो अक्सर ऐसा नहीं होता है। एक रूप आवश्यक रूप से एक मॉडल से बंधा नहीं है - यह कई मॉडलों से बंधा हो सकता है। इस मामले में कि मॉडल फ़ील्ड और फ़ॉर्म फ़ील्ड में 1: 1 संबंध है, तो हाँ, मॉडलफ़ॉर्म बहुत बेहतर विकल्प है।
ashchristopher

44

Django- विजेट-ट्विक्स का उपयोग करें , यह उपयोग करना आसान है और बहुत अच्छी तरह से काम करता है।

अन्यथा यह कस्टम टेम्पलेट फ़िल्टर का उपयोग करके किया जा सकता है।

आपको अपना फॉर्म इस प्रकार प्रस्तुत करने पर विचार करना:

<form action="/contact/" method="post">
    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="id_subject">Email subject:</label>
        {{ form.subject }}
    </div>
</form>

form.subject का एक उदाहरण है BoundField जो as_widget विधि।

आप "my_app / templatetags / myfilters.py" में एक कस्टम फ़िल्टर "addcss" बना सकते हैं

from django import template

register = template.Library()

@register.filter(name='addcss')
def addcss(value, arg):
    css_classes = value.field.widget.attrs.get('class', '').split(' ')
    if css_classes and arg not in css_classes:
        css_classes = '%s %s' % (css_classes, arg)
    return value.as_widget(attrs={'class': css_classes})

और फिर अपना फ़िल्टर लागू करें:

{% load myfilters %}
<form action="/contact/" method="post">
    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="id_subject">Email subject:</label>
        {{ form.subject|addcss:'MyClass' }}
    </div>
</form>

form.subjects तब "MyClass" सीएसएस वर्ग के साथ प्रदान किया जाएगा।

उममीद है कि इससे मदद मिलेगी।

EDIT 1

  • डिमजी के उत्तर के अनुसार फ़िल्टर अपडेट करें

  • Django- विजेट-ट्वीक लिंक जोड़ें

EDIT 2

  • भिड की टिप्पणी के अनुसार फ़िल्टर अपडेट करें

3
यह भी खूब रही! यह DRY है और यह डिस्प्ले लेयर को कंट्रोल लेयर से अलग करता है। मुझ से +1!
alekwisnia

1
हालाँकि, अब मैंने एक कमी देखी है। अगर मैं विजेट अट्रैक्शन में क्लास को परिभाषित करता हूं, तो वे इस 'एडक्स' फिल्टर से आगे निकल जाते हैं। क्या आपके पास कोई विचार है कि कैसे विलय किया जाए?
alekwisnia

1
मेरा मतलब है, as_widget () attr को ओवरराइड करता है। यह सुनिश्चित करने के लिए कि यह मौजूदा एट्रस का उपयोग कैसे करता है और उन्हें नए के साथ विस्तारित करता है?
एलेकविसनिया

मौजूदा फील्ड क्लासेस का सम्मान करने के बारे में यह उत्तर देखें
डिमजी

get('class', None).split(' ')यदि टैग में वर्ग गुण नहीं है, तो विफल हो जाएगा None। इसे get('class', '').split(' ')काम करने के लिए बदल रहा है
dtasev

32

Docs.djangoproject.com पर बताई गई विधि पर विस्तार:

class MyForm(forms.Form): 
    comment = forms.CharField(
            widget=forms.TextInput(attrs={'size':'40'}))

मैंने सोचा कि हर क्षेत्र के लिए देशी विजेट प्रकार को जानना मुश्किल था, और एक फॉर्म फ़ील्ड पर केवल क्लास नाम डालने के लिए डिफ़ॉल्ट को ओवरराइड करना मज़ेदार था। यह मेरे लिए काम करने लगता है:

class MyForm(forms.Form): 
    #This instantiates the field w/ the default widget
    comment = forms.CharField()

    #We only override the part we care about
    comment.widget.attrs['size'] = '40'

यह मुझे थोड़ा साफ लगता है।


यह ठीक वही है जो अन्य लोगों ने कहा है, उम्र पहले, सिवाय इसके कि आप इसे 'वर्ग' के बजाय 'आकार' के साथ कर रहे हैं, जो अनुरोध किया गया था।
क्रिस मॉर्गन

3
@ क्रिस मॉर्गन वास्तव में, वह पहली बार घोषणा में "comment.widget.attrs" का उपयोग करने का सुझाव देने के लिए सबसे पहले है (इसके बजाय init के साथ खिलवाड़ या इसे देखने में कर रहा है)।
डार्विनसुरिवोर

29

यदि आप चाहते हैं कि फॉर्म के सभी क्षेत्र एक निश्चित वर्ग को प्राप्त करने के लिए हैं, तो आप सिर्फ एक मूल वर्ग को परिभाषित करते हैं, जो विरासत में मिला है forms.ModelFormऔर फिर उससे विरासत में मिला है।

class BaseForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(BaseForm, self).__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'someClass'


class WhateverForm(BaseForm):
    class Meta:
        model = SomeModel

इससे मुझे 'form-control'कोड के प्रतिकृति को जोड़ने के बिना अपने आवेदन के सभी रूपों में सभी क्षेत्रों में कक्षा को जोड़ने में मदद मिली ।


1
कृपया अपरकेस के साथ वर्ग के नाम शुरू करें (साथ ही, बेसफोर्म इसके लिए बहुत बेहतर नाम लगता है)
अल्वारो

16

यहाँ दृश्य में परिवर्तन करने का सरल तरीका है। इसे टेम्पलेट में पास करने से ठीक पहले देखने के लिए नीचे जोड़ें।

form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}

14

केवल निम्नानुसार वर्गों को अपने फॉर्म में जोड़ें।

class UserLoginForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(
        attrs={
        'class':'form-control',
        'placeholder':'Username'
        }
    ))
    password = forms.CharField(widget=forms.PasswordInput(
        attrs={
        'class':'form-control',
        'placeholder':'Password'
        }
    ))

5

यहाँ ऊपर एक भिन्नता है जो सभी क्षेत्रों को एक ही वर्ग देगा (जैसे jquery अच्छा गोल कोनों)।

  # Simple way to assign css class to every field
  def __init__(self, *args, **kwargs):
    super(TranslatedPageForm, self).__init__(*args, **kwargs)
    for myField in self.fields:
      self.fields[myField].widget.attrs['class'] = 'ui-state-default ui-corner-all'


2

उदाहरण के लिए, यदि आप अपने विचारों को देखे बिना 3 पार्टी ऐप्स को संशोधित करना चाहते हैं तो ऐसे मामलों में उदाहरण के लिए आप टेम्पलेट में किसी फॉर्म के क्षेत्र में क्लास को जोड़ना चाहते हैं (व्यूहोम या फॉर्म-थ्रीडी में नहीं)। में Charlesthk जवाब बहुत सुविधाजनक है। लेकिन इस उत्तर में टेम्प्लेट फ़िल्टर किसी भी मौजूदा वर्गों को ओवरराइड करता है जो फ़ील्ड हो सकता है।

मैंने इसे एक एडिट के रूप में जोड़ने की कोशिश की लेकिन इसे एक नए उत्तर के रूप में लिखे जाने का सुझाव दिया गया।

तो, यहां एक टेम्प्लेट टैग है जो फ़ील्ड के मौजूदा वर्गों का सम्मान करता है:

from django import template

register = template.Library()


@register.filter(name='addclass')
def addclass(field, given_class):
    existing_classes = field.field.widget.attrs.get('class', None)
    if existing_classes:
        if existing_classes.find(given_class) == -1:
            # if the given class doesn't exist in the existing classes
            classes = existing_classes + ' ' + given_class
        else:
            classes = existing_classes
    else:
        classes = given_class
    return field.as_widget(attrs={"class": classes})

तुम्हारे सुझाव के लिए धन्यवाद। मैंने अपने उत्तर को अधिक "पाइथोनिक" दृष्टिकोण के अनुसार संपादित किया।
Charlesthk

महान !!, कि मैं क्या देख रहा था
ugali soft

1

जैसा कि यह पता चलता है कि आप इसे फॉर्म कंस्ट्रक्टर ( इनिट फ़ंक्शन) के रूप में या फॉर्म क्लास शुरू होने के बाद कर सकते हैं । यह कभी-कभी आवश्यक होता है यदि आप अपना स्वयं का फॉर्म नहीं लिख रहे हैं और यह फॉर्म कहीं और से आ रहा है -

def some_view(request):
    add_css_to_fields = ['list','of','fields']
    if request.method == 'POST':
        form = SomeForm(request.POST)
        if form.is_valid():
            return HttpResponseRedirect('/thanks/')
    else:
        form = SomeForm()

    for key in form.fields.keys():
        if key in add_css_to_fields:
            field = form.fields[key]
            css_addition = 'css_addition '
            css = field.widget.attrs.get('class', '')
            field.widget.attrs['class'] = css_addition + css_classes

    return render(request, 'template_name.html', {'form': form})

1

आप Django क्रिस्पी फॉर्म का भी उपयोग कर सकते हैं , यदि आप बूटस्ट्रैप या फ़ाउंडेशन जैसे कुछ सीएसएस फ्रेमवर्क का उपयोग करना चाहते हैं तो यह प्रपत्रों को परिभाषित करने का एक बढ़िया उपकरण है। और वहां आपके फॉर्म फ़ील्ड के लिए कक्षाएं निर्दिष्ट करना आसान है।

आपका फॉर्म वर्ग इस प्रकार होगा:

from django import forms

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, Submit, Field
from crispy_forms.bootstrap import FormActions

class SampleClass(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    django_hacker = forms.BooleanField(required=False)

    helper = FormHelper()
    helper.form_class = 'your-form-class'
    helper.layout = Layout(
        Field('name', css_class='name-class'),
        Field('age', css_class='age-class'),
        Field('django_hacker', css-class='hacker-class'),
        FormActions(
            Submit('save_changes', 'Save changes'),
        )
    )
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.