CSS-Styling in Django-Formen

Wie gestalte ich Folgendes:

in forms.py –

from django import forms class ContactForm(forms.Form): subject = forms.CharField(max_length=100) email = forms.EmailField(required=False) message = forms.CharField(widget=forms.Textarea) 

in Kontakt_formular.html –

  
{{ form.as_table }}

Wie lege ich zum Beispiel eine class oder ID für den Betreff, die E-Mail-Nachricht oder die Nachricht fest, um ein externes Stylesheet bereitzustellen? Vielen Dank

Aus meiner Antwort auf: Wie man Formularfelder mit

in Django auszeichnet

 class MyForm(forms.Form): myfield = forms.CharField(widget=forms.TextInput(attrs={'class' : 'myfieldclass'})) 

oder

 class MyForm(forms.ModelForm): class Meta: model = MyModel def __init__(self, *args, **kwargs): super(MyForm, self).__init__(*args, **kwargs) self.fields['myfield'].widget.attrs.update({'class' : 'myfieldclass'}) 

oder

 class MyForm(forms.ModelForm): class Meta: model = MyModel widgets = { 'myfield': forms.TextInput(attrs={'class': 'myfieldclass'}), } 

— BEARBEITEN —
Das oben genannte ist die einfachste Änderung, die an dem Code der ursprünglichen Frage vorgenommen werden kann, der erfüllt, was gefragt wurde. Es verhindert auch, dass Sie sich wiederholen, wenn Sie das Formular an anderen Stellen wiederverwenden. Ihre classn oder andere Attribute funktionieren nur, wenn Sie die Formularmethoden as_table / as_ul / as_p von Django verwenden. Wenn Sie die vollständige Kontrolle für ein vollständig benutzerdefiniertes Rendering benötigen, ist dies eindeutig dokumentiert

– EDIT 2 —
Es wurde eine neuere Methode hinzugefügt, um Widget und Attribute für ein ModelForm anzugeben.

Dies kann mit einem benutzerdefinierten Vorlagenfilter erfolgen. wenn du denkst, dass du deine Form so bildest:

 
{{ form.non_field_errors }}
{{ form.subject.errors }} {{ form.subject.label_tag }} {{ form.subject }} {{ form.subject.help_text }}

form_subject ist eine Instanz von BoundField mit der Methode as_widget .

Sie können einen benutzerdefinierten Filter “addclass” in “my_app / templatetags / myfilters.py” erstellen

 from django import template register = template.Library() @register.filter(name='addclass') def addclass(value, arg): return value.as_widget(attrs={'class': arg}) 

Und dann wende deinen Filter an:

 {% load myfilters %} 
{{ form.non_field_errors }}
{{ form.subject.errors }} {{ form.subject.label_tag }} {{ form.subject|addclass:'MyClass' }} {{ form.subject.help_text }}

form_subjects wird dann mit der CSS-class “MyClass” gerendert.

Ich hoffe das hilft.

Wenn Sie dem Formular keinen Code hinzufügen möchten (wie in den Kommentaren zu @ shafcs Antwort erwähnt), ist es sicherlich möglich, hier sind zwei Optionen.

Zuerst referenzieren Sie die einzelnen Felder im HTML-Code und nicht das gesamte Formular auf einmal:

 
  • {{ form.subject }}
  • {{ form.email }}
  • {{ form.message }}

(Beachten Sie, dass ich es auch in eine unsortierte Liste geändert habe.)

Zweitens, beachten Sie in den Dokumenten zur Ausgabe von Formularen als HTML , Django:

Die Feld-ID wird generiert, indem ‘id_’ dem Feldnamen vorangestellt wird. Die ID-Attribute und -Tags sind standardmäßig in der Ausgabe enthalten.

Alle Ihre Formularfelder haben bereits eine eindeutige ID . Sie würden also id_subject in Ihrer CSS-Datei referenzieren, um das Betreff- Feld zu formatieren . Ich sollte beachten, dass sich das Formular verhält, wenn Sie den Standard- HTML-Code verwenden, der nur das Drucken des Formulars und nicht die einzelnen Felder erfordert:

 
    {{ form }} # Will auto-generate HTML with id_subject, id_email, email_message {{ form.as_ul }} # might also work, haven't tested

Siehe den vorherigen Link für andere Optionen bei der Ausgabe von Formularen (Sie können Tabellen, usw.).

Hinweis – Ich weiß, das ist nicht das Gleiche wie das Hinzufügen einer class zu jedem Element (wenn Sie dem Formular ein Feld hinzugefügt haben, müssten Sie auch das CSS aktualisieren) – aber es ist einfach genug, alle Felder nach ID zu referenzieren in Ihrem CSS so:

 #id_subject, #id_email, #email_message {color: red;} 

Du kannst das so machen:

 class ContactForm(forms.Form): subject = forms.CharField(max_length=100) subject.widget.attrs.update({'id' : 'your_id'}) 

Hoffe das funktioniert.

Ignas

In diesem Blogeintrag können Sie CSS-classn mithilfe eines benutzerdefinierten Vorlagenfilters zu Ihren Feldern hinzufügen.

 from django import template register = template.Library() @register.filter(name='addcss') def addcss(field, css): return field.as_widget(attrs={"class":css}) 

Legen Sie dies in die Vorlagetags / Ordner Ihrer App und Sie können dies jetzt tun

 {{field|addcss:"form-control"}} 

Sie können diese Bibliothek verwenden: https://pypi.python.org/pypi/django-widget-tweaks

Es ermöglicht Ihnen Folgendes:

 {% load widget_tweaks %}  {{ form.title|add_class:"css_class_1 css_class_2" }} 

Du kannst tun:

 
{% for field in form %} {% endfor %}
{{field}}

Dann können Sie classn / IDs zum Beispiel dem Tag

hinzufügen. Sie können natürlich alle anderen Tags verwenden, die Sie möchten. Überprüfen Sie das Arbeiten mit Django-Formularen als Beispiel, was für jedes field im Formular verfügbar ist ( {{field}} zum Beispiel gibt nur das Eingabe-Tag aus, nicht das Label usw.).

Sie müssen Ihre Formularklasse ” __init__ möglicherweise nicht überschreiben, da Django die Attribute name und id in den HTML- input festlegt. Sie können CSS wie folgt haben:

 form input[name='subject'] { font-size: xx-large; } 

Habe diesen hier wirklich nicht gesehen …

https://docs.djangoproject.com/en/1.8/ref/forms/api/#more-granular-output

Granularere Ausgabe

Die Methoden as_p (), as_ul () und as_table () sind einfache Verknüpfungen für faule Entwickler – sie sind nicht die einzige Möglichkeit, ein Formularobjekt anzuzeigen.

class BoundField Wird verwendet, um HTML- oder Zugriffsattribute für ein einzelnes Feld einer Form-Instanz anzuzeigen.

Die Methode str () ( Unicode in Python 2) dieses Objekts zeigt den HTML-Code für dieses Feld an.

Um ein einzelnes BoundField abzurufen, verwenden Sie die Wörterbuchsuchsyntax in Ihrem Formular unter Verwendung des Feldnamens als Schlüssel:

 >>> form = ContactForm() >>> print(form['subject'])  

Um alle BoundField-Objekte abzurufen, durchlaufen Sie das Formular:

 >>> form = ContactForm() >>> for boundfield in form: print(boundfield)     

Die feldspezifische Ausgabe berücksichtigt die Einstellung auto_id des Formularobjekts:

 >>> f = ContactForm(auto_id=False) >>> print(f['message'])  >>> f = ContactForm(auto_id='id_%s') >>> print(f['message'])  

Eine Lösung besteht darin, JavaScript zu verwenden, um die erforderlichen CSS-classn hinzuzufügen, nachdem die Seite fertig ist. Zum Beispiel styled django form output mit Bootstrap-classn (jQuery wird der Kürze halber verwendet):

  

Dies vermeidet die Hässlichkeit des Mischens von Styling-Besonderheiten mit Ihrer Geschäftslogik.

Es gibt ein sehr einfach zu installierendes und tolles Werkzeug für Django, das ich für das Styling verwende und es kann für jedes Frontend-Framework wie Bootstrap, Materialize, Foundation usw. verwendet werden. Es heißt Widget-Tweaks Dokumentation: Widget Tweaks

  1. Sie können es mit den generischen Ansichten von Django verwenden
  2. Oder mit deinen eigenen Formen:

von Django-Importformularen

 class ContactForm(forms.Form): subject = forms.CharField(max_length=100) email = forms.EmailField(required=False) message = forms.CharField(widget=forms.Textarea) 

Anstatt Standard zu verwenden:

 {{ form.as_p }} or {{ form.as_ul }} 

Sie können es auf Ihre eigene Weise bearbeiten, indem Sie das render_field-Attribut verwenden, das Ihnen eine html-ähnliche Form gibt, wie in diesem Beispiel:

Vorlage.html

 {% load widget_tweaks %} 
{% render_field form.subject class+="form-control myCSSclass" placeholder="Enter your subject here" %}
{% render_field form.email type="email" class+="myCSSclassX myCSSclass2" %}
{% render_field form.message class+="myCSSclass" rows="4" cols="6" placeholder=form.message.label %}

Diese Bibliothek gibt Ihnen die Möglichkeit, Ihr Frontend von Ihrem Backend zu trennen

In Django 1.10 (möglicherweise auch früher) können Sie es wie folgt tun.

Modell:

 class Todo(models.Model): todo_name = models.CharField(max_length=200) todo_description = models.CharField(max_length=200, default="") todo_created = models.DateTimeField('date created') todo_completed = models.BooleanField(default=False) def __str__(self): return self.todo_name 

Bilden:

 class TodoUpdateForm(forms.ModelForm): class Meta: model = Todo exclude = ('todo_created','todo_completed') 

Vorlage:

 
{% csrf_token %} {{ form.non_field_errors }}
{{ form.todo_name.errors }} {{ form.todo_name }}
{{ form.todo_description.errors }} {{ form.todo_description }}

Edit: Eine andere (etwas bessere) Art zu tun, was ich vorschlage ist hier beantwortet: Django Form Eingabefeld Styling

Alle oben genannten Optionen sind großartig, nur gedacht, dass ich diese hier eincasting würde, weil es anders ist.

Wenn Sie benutzerdefinierte Formen, classn usw. in Ihren Formularen verwenden möchten, können Sie eine HTML-Eingabe in Ihrer Vorlage vornehmen, die mit Ihrem Formularfeld übereinstimmt. Für ein CharField zum Beispiel (das Standard-Widget ist TextInput ), nehmen wir an, Sie möchten eine Bootstrap-looking Texteingabe. Sie würden so etwas tun:

Und solange Sie den Namen des Formularfelds mit dem HTML-Namensattribut übereinstimmen (und das Widget wahrscheinlich auch dem Eingabetyp entsprechen muss), führt Django beim Ausführen von validate oder form.is_valid() dieselben validate für dieses Feld aus. und

Das Formatieren anderer Dinge wie Labels, Fehlermeldungen und form.field.error.as_text erfordert keine große Problemumgehung, da Sie etwas wie form.field.error.as_text und sie form.field.error.as_text können. Die tatsächlichen Felder sind diejenigen, die etwas Fiedeln erfordern.

Ich weiß nicht, ob das der beste Weg ist oder wie ich es empfehlen würde, aber es ist ein Weg, und es könnte für jemanden richtig sein.

Im Folgenden finden Sie eine nützliche Anleitung für das Entcasting von Formularen, die die meisten Antworten enthält, die in SO aufgelistet sind (z. B. die Attr-Einstellung für Widgets und Widget-Optimierungen). https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manuell.html