2009-08-10 3 views
19

Gibt es eine clevere Möglichkeit, Django-Formulare Felder mit Sternchen nach Feldern, die erforderlich sind, zu machen? Oder um ein anderes cleveres zur Markierung von Pflichtfeldern zu bieten? Ich möchte es nicht noch einmal in einer Vorlage machen müssen, wenn ich bereits ein Feld wie im Formular erforderlich gesetzt habe.Wie Formularfeld mit Informationen, dass es erforderlich ist, rendern

Antwort

29

Ab Django 1.2, wenn Ihr Formular ein Attribut mit dem Namen required_css_class hat, wird es zu BoundField.css_classes für erforderliche Felder hinzugefügt. Sie können dann CSS verwenden, um die gewünschten Teile des Formulars wie gewünscht zu formatieren. Ein typischer Anwendungsfall:

# views.py 
class MyForm(django.forms.Form): 
    required_css_class = 'required' 
    … 

...

/* CSS */ 
th.required { font-weight: bold; } 

...

<!-- HTML --> 
<tr> 
    <th class="{{form.name.css_classes}}">{{form.name.label_tag}}</th> 
    <td>{{form.name.errors}}{{form.name}}</td> 
</tr> 

Wenn Sie Form.as_table() verwenden, Form.as_ul und Form.as_p, sie dies automatisch, und fügte hinzu, die Klasse zu <tr>, <li> und <p>, jeweils.

+8

Hinweis: Sie können die css content-Direktive verwenden, um ein Sternchen mit derselben Methode hinzuzufügen: 'th.required: after {content: '*'}' –

1

Der beste Weg für solche Zwecke, die ich gefunden habe, ist die Ausgabe des Formulars über eine HTML-Vorlage zu machen. Wie dies zu tun ist, wird beschrieben here. Mit etwas Glück setzt das Beispiel ein Sternchen nach Pflichtfeldern, so wie Sie es möchten.

+0

Keiner meiner Formen gemacht wird {{form}}, ich Felder explizit nennen, weil ich in der Regel nur Teilmenge von Formularfeldern angezeigt werden soll. Ich brauche etwas Niedrigeres, wie ein Attribut eines Feldes oder eines Widgets. – gruszczy

+0

Wenn Sie über Modellformen sprechen und die Eigenschaft 'fields' der Meta-Klasse verwenden, um eine Teilmenge der anzuzeigenden Felder zu bestimmen, funktioniert dies. Wenn Sie nicht modellierte Formulare haben und ausgeblendete Felder haben, wird es wieder funktionieren. Ich bin in Eile, Entschuldigung, wenn ich etwas verpasse? – shanyu

+0

Ich habe ein einzelnes Formular, das in vielen Vorlagen verwendet wird, und ich rufe normalerweise alle Felder an, die ich in der Vorlage benötige. Aus diesem Grund kann ich kein Vorlagen-Rendering verwenden. Aber es scheint, es wäre besser, wenn ich nur einige Unterklassen mit Meta erstellen und dann dieses Templating verwenden würde. Das ist eine gute Idee, ich muss darüber nachdenken. – gruszczy

1

Ich verwende ein Template-Tag, um Formularfelder mit ihren Beschriftungen und Fehlern, plus ein Sternchen und eine CSS-Klasse für Pflichtfelder zu rendern. Es gibt verschiedene Snippets auf www.djangosnippets.org.

+0

So mache ich im Moment, ich meine, ich benutze einen Filter, um dies zu tun. Trotzdem ist das nicht sehr trocken. Ich würde es vorziehen, diese Einstellung in die Form zu bringen (einige 'mark_required = True' in Form). – gruszczy

0

Ich habe versucht, etwas wie diese, dh überschreiben die Standard-Template-Tag (dies fügt ein rotes Sternchen in der Admin-Schnittstelle für erforderliche nicht-Nur-Lesen-Felder. Dann habe ich auch ein 2. Tag für meine Ansichten, die Inline-und Blockieren Etikett, um den Code Siehe unten (kopieren/Einfügen von Django Quellcode mit einigen Modifikationen.):

In settings.py:

from django.forms.util import flatatt 
from django.utils.html import conditional_escape 
from django.utils.safestring import mark_safe 
import django.forms.forms as django_forms 
def custom_label_tag(self, contents=None, attrs=None): 
     """ 
     Wraps the given contents in a <label>, if the field has an ID attribute. 
     Does not HTML-escape the contents. If contents aren't given, uses the 
     field's HTML-escaped label. 

     If attrs are given, they're used as HTML attributes on the <label> tag. 
     """ 
     contents = contents or conditional_escape(self.label) 
     widget = self.field.widget 
     id_ = widget.attrs.get('id') or self.auto_id 
     if id_: 
      attrs = attrs and flatatt(attrs) or '' 
      if self.field.required: 
       label = unicode(contents) 
       label_suffix = "" 
       if label[-1] == ":": 
        label = label[:-1] 
        label_suffix += ":" 
       contents = u'<label for="%s"%s>%s<span style="color:red;">*</span>%s</label>' % (widget.id_for_label(id_), attrs, label, label_suffix) 
      else: 
       contents = u'<label for="%s"%s>%s</label>' % (widget.id_for_label(id_), attrs, unicode(contents)) 
     return mark_safe(contents) 

def custom_inline_label_tag(self, contents=None, attrs=None): 
    if attrs: 
     if "class" in attrs.keys(): 
      attrs["class"] += " inline" 
     else: 
      attrs["class"] = "inline" 
    else: 
     attrs = {"class": "inline"} 
    return self.label_tag(contents, attrs) 
django_forms.BoundField.label_tag = custom_label_tag # override django method 
django_forms.BoundField.inline_label_tag = custom_inline_label_tag 

In meinen Vorlagen

<p>{{ form.fieldname.errors}}{{ form.fieldname.inline_label_tag }}{{form.fieldname}}</p> 
OR 
<p>{{ form.fieldname.errors}}{{ form.fieldname.label_tag }}{{form.fieldname}}</p> 
2

Sie können auch eine field.field.required Eigenschaft:

{% for field in form %} 
    {{field.label}} {% if field.field.required %} * {% endif %} 
    {{field}} 
    {{field.errors}} 
{% endfor %} 
Verwandte Themen