it-swarm.com.de

Ändern Sie die Größe der Felder in Django Admin

Django füllt beim Hinzufügen oder Bearbeiten von Einträgen im Admin normalerweise den horizontalen Bereich aus. In manchen Fällen ist dies jedoch eine echte Platzverschwendung, wenn z. B. ein Datumsfeld mit einer Breite von 8 Zeichen oder ein CharField mit 6 oder 8 bearbeitet wird Zeichen breit, und dann geht das Editierfeld auf 15 oder 20 Zeichen.

Wie kann ich dem Administrator mitteilen, wie breit ein Textfeld sein soll oder wie hoch ein TextField-Bearbeitungsfeld ist?

99
Andor

Sie sollten ModelAdmin.formfield_overrides verwenden.

Es ist ziemlich einfach - in admin.py definieren Sie:

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)

Vergessen Sie nicht, dass Sie geeignete Klassen importieren sollten - in diesem Fall:

from Django.forms import TextInput, Textarea
from Django.db import models
184
jki

Sie können beliebige HTML-Attribute für ein Widget festlegen, indem Sie die Eigenschaft "attrs" verwenden.

Sie können dies im Django-Administrator mit formfield_for_dbfield tun:

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

oder mit einer benutzerdefinierten Widget-Unterklasse und dem Wörterbuch 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}}
42
Carl Meyer

Eine schnelle und unpassende Option besteht darin, einfach eine benutzerdefinierte Vorlage für das betreffende Modell bereitzustellen. 

Wenn Sie eine Vorlage mit dem Namen admin/<app label>/<class name>/change_form.html erstellen, verwendet der Administrator diese Vorlage anstelle der Standardeinstellung. Wenn Sie also ein Modell mit dem Namen Person in einer App mit dem Namen people haben, erstellen Sie eine Vorlage mit dem Namen admin/people/person/change_form.html.

Alle Admin-Vorlagen haben einen extrahead-Block, den Sie überschreiben können, um Sachen in <head> zu platzieren. Der letzte Teil des Puzzles ist die Tatsache, dass jedes Feld eine HTML-ID mit id_<field-name> hat.

So könnten Sie etwa Folgendes in Ihre Vorlage einfügen:

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

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

Zum Ändern der Breite für ein bestimmtes Feld.

Erstellt über 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
21
alanjds

Wenn Sie die Attribute in einer Instanz pro Feld ändern möchten, können Sie die Eigenschaft "attrs" direkt in Ihre Formulareinträge einfügen.

zum Beispiel:

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')

Die "attrs" -Eigenschaft übergibt im Wesentlichen das HTML-Markup, mit dem das Formularfeld angepasst wird. Jeder Eintrag ist ein Tupel des Attributs, das Sie überschreiben möchten, und den Wert, mit dem Sie es überschreiben möchten. Sie können so viele Attribute eingeben, wie Sie möchten, solange Sie jeden Tupel mit einem Komma trennen.

10
Jonathan

Der beste Weg, den ich gefunden habe, ist etwa so:

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

Es ist viel besser für ModelForm als das Überschreiben von Feldern mit verschiedenen Widgets, da dabei name- und help_text-Attribute sowie Standardwerte von Modellfeldern beibehalten werden, sodass Sie sie nicht in Ihr Formular kopieren müssen. 

7
kurczak

Ich hatte ein ähnliches Problem mit TextField. Ich verwende Django 1.0.2 und wollte den Standardwert für 'Zeilen' im zugehörigen Textbereich ändern. formfield_overrides existiert in dieser Version nicht. Das Überschreiben von formfield_for_dbfield hat funktioniert, aber ich musste es für jede meiner ModelAdmin-Unterklassen tun, da dies einen Rekursionsfehler zur Folge hatte. Schließlich fand ich, dass das Hinzufügen des folgenden Codes zu models.py funktioniert:

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)

Verwenden Sie dann MyTextField anstelle von TextField, wenn Sie Ihre Modelle definieren. Ich habe es von dieser Antwort auf eine ähnliche Frage angepasst.

7
msdin

Sie können die Größe der Felder immer in einem benutzerdefinierten Stylesheet festlegen und Django anweisen, diese für Ihre ModelAdmin-Klasse zu verwenden:

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

Es ist gut beschrieben in Django FAQ :

F: Wie ändere ich die Attribute für ein Widget in einem Feld in meinem Modell?

A: Überschreibt das Feld formfield_for_db in der Klasse ModelAdmin/StackedInline/TabularInline 

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)
5
HardQuestions

für 1.6 musste ich unter Verwendung von Formularen die Attribute des Textbereichs innerhalb des Zeichenfelds angeben:

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

Gleiche Antwort wie msdin, jedoch mit TextInput statt TextArea:

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
dan-klasson

Und noch ein Beispiel:

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

Wenn Sie nur eine bestimmte Feldgröße bearbeiten möchten, können Sie diese verwenden.

0
mevaka

Wenn Sie mit einem ForeignKey-Feld arbeiten, das Auswahlmöglichkeiten/Optionen/ein Dropdown-Menü enthält, können Sie formfield_for_foreignkey in der Admin-Instanz überschreiben:

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)

Weitere Informationen zu dieser Anleitung hier und hier .

0
Matt Ian Hong

Hier ist eine einfache und dennoch flexible Lösung. Verwenden Sie ein benutzerdefiniertes Formular, um einige Widgets zu überschreiben.

# 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

Die in ElephantForm angegebenen Widgets ersetzen die Standard-Widgets. Der Schlüssel ist die Zeichenfolgendarstellung des Feldes. Felder, die nicht im Formular angegeben sind, verwenden das Standard-Widget.

Obwohl age eine IntegerField ist, können wir das TextInput-Widget verwenden, da NumberInput anders als TextInput das size-Attribut akzeptiert.

Diese Lösung wird in in diesem Artikel beschrieben.

0