Django व्यवस्थापक में फ़ील्ड का आकार बदलें


107

Django व्यवस्थापक पर प्रविष्टियों को जोड़ने या संपादित करते समय क्षैतिज स्थान को भरने के लिए जाता है, लेकिन, कुछ मामलों में, अंतरिक्ष की एक वास्तविक बर्बादी है, जब, अर्थात, दिनांक फ़ील्ड, 8 वर्ण चौड़े, या एक CharField, भी 6 या 8 का संपादन। चौड़े चौड़े, और फिर संपादन बॉक्स 15 या 20 चार्ट तक जाता है।

मैं व्यवस्थापक को कैसे बता सकता हूं कि एक टेक्स्टबॉक्स कितना चौड़ा होना चाहिए, या टेक्स्ट टेक्स्ट एडिट बॉक्स की ऊंचाई कितनी होनी चाहिए?


9
जाहिर है, आप इस मामले में ऐसा करना भूल गए। दो साल से अधिक समय बाद। =)
कास्परऑने २०'१२

प्रोजेक्ट बिगड़ गया और मुझे कुछ समय के लिए कोड देखने को नहीं मिला। मैं अगले महीने एक नई परियोजना शुरू कर सकता हूं, इसलिए हो सकता है कि मैं इसे फिर से
सील कर दूं

जवाबों:


209

आपको ModelAdmin.formfield_overrides का उपयोग करना चाहिए ।

यह काफी आसान है - में admin.py, परिभाषित:

from django.forms import TextInput, Textarea
from django.db import models

class YourModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'20'})},
        models.TextField: {'widget': Textarea(attrs={'rows':4, 'cols':40})},
    }

admin.site.register(YourModel, YourModelAdmin)

1
यह वही था जो मैं कुछ हास्यास्पद टेम्पलेट अनुकूलन बनाने के लिए देख रहा था। धन्यवाद!
क्रिस

2
ध्यान दें कि यह काम नहीं करेगा filter_horizontalया filter_verticalYourModelAdmin में संबंधित फ़ील्ड के लिए सेट किया गया है। मैंने यह पता लगाने के लिए कुछ समय बिताया है।
डेनिस गोलोमेज़ोव

क्या किसी रूप में इसको लेकर कोई उत्सुकता है? मुझे सभी Textareas के लिए attrs विशेषता सेट करने का एक तरीका नहीं मिला।
जूलियन

1
मैंने केवल उपयोग किया models.TextField: {'widget': Textarea(attrs={'rows':4})}लेकिन चौड़ाई भी छोटी हो गई।
स्मित जॉन्थ

जाहिरा तौर पर उन्हें एक ही आकार देना मुश्किल है।
सोरेन

44

आप अपनी "अटार्स" संपत्ति का उपयोग करके विजेट पर मनमाने ढंग से HTML विशेषताओं को सेट कर सकते हैं

आप यह Django व्यवस्थापक में formfield_for_dbfield का उपयोग करके कर सकते हैं:

class MyModelAdmin(admin.ModelAdmin):
  def formfield_for_dbfield(self, db_field, **kwargs):
    field = super(ContentAdmin, self).formfield_for_dbfield(db_field, **kwargs)
    if db_field.name == 'somefield':
      field.widget.attrs['class'] = 'someclass ' + field.widget.attrs.get('class', '')
    return field

या एक कस्टम विजेट उपवर्ग और formfield_overrides शब्दकोश के साथ :

class DifferentlySizedTextarea(forms.Textarea):
  def __init__(self, *args, **kwargs):
    attrs = kwargs.setdefault('attrs', {})
    attrs.setdefault('cols', 80)
    attrs.setdefault('rows', 5)
    super(DifferentlySizedTextarea, self).__init__(*args, **kwargs)

class MyModelAdmin(admin.ModelAdmin):
  formfield_overrides = { models.TextField: {'widget': DifferentlySizedTextarea}}

29

एक विशिष्ट क्षेत्र के लिए चौड़ाई बदलने के लिए।

ModelAdmin.get_form द्वारा बनाया गया :

class YourModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super(YourModelAdmin, self).get_form(request, obj, **kwargs)
        form.base_fields['myfield'].widget.attrs['style'] = 'width: 45em;'
        return form

मेरी राय में यह सबसे अच्छा जवाब है, क्योंकि यह एक नया रूप बनाने के लिए अलग-अलग क्षेत्रों को बदलने की अनुमति देता है।
rbennell

20

एक त्वरित और गंदा विकल्प केवल प्रश्न में मॉडल के लिए एक कस्टम टेम्पलेट प्रदान करना है।

यदि आप नाम से एक टेम्प्लेट बनाते हैं, admin/<app label>/<class name>/change_form.htmlतो व्यवस्थापक डिफ़ॉल्ट के बजाय उस टेम्प्लेट का उपयोग करेगा। यही है, यदि आपको नाम के Personऐप में एक मॉडल मिला है, तो आप नाम का peopleएक टेम्पलेट बनाएंगे admin/people/person/change_form.html

सभी एडमिन टेम्प्लेट में एक extraheadब्लॉक होता है जिसमें आप सामान को अंदर रख सकते हैं <head>और पहेली का अंतिम टुकड़ा तथ्य यह है कि हर क्षेत्र में HTML आईडी है id_<field-name>

तो, आप अपने टेम्प्लेट में निम्नलिखित कुछ डाल सकते हैं:

{% extends "admin/change_form.html" %}

{% block extrahead %}
  {{ block.super }}
  <style type="text/css">
    #id_my_field { width: 100px; }
  </style>
{% endblock %}

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

10

यदि आप प्रति फ़ील्ड उदाहरण पर विशेषताओं को बदलना चाहते हैं, तो आप सीधे "फ़ॉर्म" संपत्ति को अपनी फॉर्म प्रविष्टियों में जोड़ सकते हैं।

उदाहरण के लिए:

class BlogPostForm(forms.ModelForm):
    title = forms.CharField(label='Title:', max_length=128)
    body = forms.CharField(label='Post:', max_length=2000, 
        widget=forms.Textarea(attrs={'rows':'5', 'cols': '5'}))

    class Meta:
        model = BlogPost
        fields = ('title', 'body')

"अटार्स" संपत्ति मूल रूप से HTML मार्कअप के साथ गुजरती है जो प्रपत्र फ़ील्ड को समायोजित करेगी। प्रत्येक प्रविष्टि उस विशेषता का एक हिस्सा है जिसे आप ओवरराइड करना चाहते हैं और उस मूल्य को जिसके साथ आप इसे ओवरराइड करना चाहते हैं। जब तक आप प्रत्येक टपल को अल्पविराम से अलग करते हैं, तब तक आप जितनी चाहें उतनी विशेषताएँ दर्ज कर सकते हैं।


IMO एक ही फ़ील्ड को संशोधित करने का सबसे अच्छा तरीका है और सभी TextInput- विजेट्स को एक बार में (जैसे स्वीकृत उत्तर नहीं देता है)
ascripter

7

सबसे अच्छा तरीका मुझे कुछ इस तरह मिला है:

class NotificationForm(forms.ModelForm):
    def __init__(self, *args, **kwargs): 
        super(NotificationForm, self).__init__(*args, **kwargs)
        self.fields['content'].widget.attrs['cols'] = 80
        self.fields['content'].widget.attrs['rows'] = 15
        self.fields['title'].widget.attrs['size'] = 50
    class Meta:
        model = Notification

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


7

मुझे TextField के साथ एक समान समस्या थी। मैं Django 1.0.2 का उपयोग कर रहा हूं और संबद्ध टेक्स्टारिया में 'पंक्तियों' के लिए डिफ़ॉल्ट मान को बदलना चाहता हूं। formfield_overrides इस संस्करण में मौजूद नहीं है। ओवरराइडिंग formfield_for_dbfield ने काम किया लेकिन मुझे इसे अपने प्रत्येक ModelAdmin उपवर्गों के लिए करना था या इसके परिणामस्वरूप एक पुनरावृत्ति त्रुटि होगी। आखिरकार, मैंने पाया कि नीचे दिए गए कोड को मॉडलहोम में जोड़ना काम करता है:

from django.forms import Textarea

class MyTextField(models.TextField):
#A more reasonably sized textarea                                                                                                            
    def formfield(self, **kwargs):
         kwargs.update(
            {"widget": Textarea(attrs={'rows':2, 'cols':80})}
         )
         return super(MyTextField, self).formfield(**kwargs)

तब अपने मॉडल को परिभाषित करते समय TextField के बजाय MyTextField का उपयोग करें। मैंने इसे इसी प्रश्न के उत्तर से अनुकूलित किया ।


5

यह अच्छी तरह से Django में वर्णित है :

प्रश्न: मैं अपने मॉडल में फ़ील्ड पर विजेट के लिए विशेषताओं को कैसे बदल सकता हूँ?

A: ModelAdmin / StackedInline / TabularInline क्लास में formfield_for_dbfield को ओवरराइड करें

class MyOtherModelInline(admin.StackedInline):
    model = MyOtherModel
    extra = 1

    def formfield_for_dbfield(self, db_field, **kwargs):
        # This method will turn all TextFields into giant TextFields
        if isinstance(db_field, models.TextField):
            return forms.CharField(widget=forms.Textarea(attrs={'cols': 130, 'rows':30, 'class': 'docx'}))
        return super(MyOtherModelInline, self).formfield_for_dbfield(db_field, **kwargs)

जब मैं इस तकनीक का उपयोग करता हूं तो सहायता पाठ दिखाई नहीं देगा, और यदि यह एक TabularInline है, तो कॉलम हेडर 'कोई नहीं' बन जाता है।
स्टीवन टी। स्नाइडर

1
यह एक अच्छा तरीका नहीं है, जैसा कि आप CharField में अन्य सभी सेटिंग्स मिटा रहे हैं। उदाहरण के लिए, डिफ़ॉल्ट रूप से, यह समझदारी से पता लगाएगा कि फॉर्म फ़ील्ड की आवश्यकता है या नहीं, लेकिन यह कोड उसे नष्ट कर देता है। आपको इसके बजाय अपने सुपर () कॉल द्वारा लौटाए गए मान पर विजेट सेट करना चाहिए।
Cerin

5

आप हमेशा अपने फ़ील्ड आकार को एक कस्टम स्टाइलशीट में सेट कर सकते हैं और Django को अपने ModelAdmin वर्ग के लिए उपयोग करने के लिए कह सकते हैं:

class MyModelAdmin(ModelAdmin):
    class Media:
        css = {"all": ("my_stylesheet.css",)}

सबसे बढ़िया उत्तर! फ़ॉर्मफ़िल्ड और विशेषताओं (और संभावित दुष्प्रभावों) के साथ कोई फ़िज़लिंग नहीं है, बस एक सीएसएस फ़ाइल है, जो कि django व्यवस्थापक रूपों में मौजूदा आईडी / कक्षाओं के साथ - आसानी से केवल कुछ या सभी क्षेत्रों को लक्षित कर सकती है। प्रसिद्ध बनें!
बेंज़कजी

2

1.6 के लिए, प्रपत्रों का उपयोग करते हुए मुझे टेक्स्टफील्ड की विशेषताओं को चारफील्ड के अंदर निर्दिष्ट करना था:

test1 = forms.CharField(max_length=400, widget=forms.Textarea( attrs={'rows':'2', 'cols': '10'}),  initial='', help_text=helptexts.helptxt['test'])

1

Msdin के रूप में एक ही उत्तर लेकिन TextArea के बजाय TextInput के साथ:

from django.forms import TextInput

class ShortTextField(models.TextField):
    def formfield(self, **kwargs):
         kwargs.update(
            {"widget": TextInput(attrs={'size': 10})}
         )
         return super(ShortTextField, self).formfield(**kwargs)

1

यहाँ एक सरल, अभी तक लचीला समाधान है। कुछ विगेट्स को ओवरराइड करने के लिए कस्टम फ़ॉर्म का उपयोग करें।

# models.py
class Elephant(models.Model):
    name = models.CharField(max_length=25)
    age = models.IntegerField()

# forms.py
class ElephantForm(forms.ModelForm):

    class Meta:
        widgets = {
            'age': forms.TextInput(attrs={'size': 3}),
        }

# admin.py
@admin.register(Elephant)
class ElephantAdmin(admin.ModelAdmin):
    form = ElephantForm

इसमें दिए गए विजेट ElephantFormडिफ़ॉल्ट लोगों को बदल देंगे। कुंजी फ़ील्ड का स्ट्रिंग प्रतिनिधित्व है। प्रपत्र में निर्दिष्ट फ़ील्ड डिफ़ॉल्ट विजेट का उपयोग नहीं करेंगे।

ध्यान दें कि यद्यपि हम ageएक विजेट का IntegerFieldउपयोग कर सकते हैं TextInput, क्योंकि इसके विपरीत NumberInput, विशेषता को TextInputस्वीकार करता है size

यह समाधान इस लेख में वर्णित है


0

यदि आप किसी विदेशीके क्षेत्र के साथ काम कर रहे हैं जिसमें विकल्प / विकल्प / एक ड्रॉपडाउन मेनू शामिल है, तो आप formfield_for_foreignkeyव्यवस्थापक उदाहरण में ओवरराइड कर सकते हैं :

class YourNewAdmin(admin.ModelAdmin):
    ...

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'your_fk_field':
            """ For your FK field of choice, override the dropdown style """
            kwargs["widget"] = django.forms.widgets.Select(attrs={
                'style': 'width: 250px;'
            })

        return super().formfield_for_foreignkey(db_field, request, **kwargs)

इस पैटर्न पर और अधिक जानकारी यहाँ और यहाँ


-1

और एक और उदाहरण भी:

class SecenekInline(admin.TabularInline):
   model = Secenek
   # classes = ['collapse']
   def formfield_for_dbfield(self, db_field, **kwargs):
       field = super(SecenekInline, self).formfield_for_dbfield(db_field, **kwargs)
       if db_field.name == 'harf':
           field.widget = TextInput(attrs={'size':2})
       return field
   formfield_overrides = {
       models.TextField: {'widget': Textarea(attrs={'rows':2})},
   }
   extra = 2

यदि आप केवल विशिष्ट फ़ील्ड आकार संपादित करना चाहते हैं, तो आप इसका उपयोग कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.