API för formulärLink to this heading

Inbundna och obundna formulärLink to this heading

En instans av Form är antingen bunden till en uppsättning data eller obunden.

  • Om det är bundet till en uppsättning data, kan det validera dessa data och rendera formuläret som HTML med de data som visas i HTML.

  • Om det är unbound kan det inte göra validering (eftersom det inte finns några data att validera!), men det kan fortfarande återge det tomma formuläret som HTML.

class FormLink to this definition

För att skapa en obunden Form-instans instansierar du klassen:

Python console
>>> f = ContactForm()

För att binda data till ett formulär skickar du data som en ordbok som första parameter till din Form-klass konstruktör:

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "contact_email": "foo@example.com",
...     "urgent": True,
... }
>>> f = ContactForm(data)

I den här ordlistan är nycklarna fältnamnen, som motsvarar attributen i din klass Form. Värdena är de data som du försöker validera. Dessa kommer vanligtvis att vara strängar, men det finns inget krav på att de ska vara strängar; typen av data du skickar beror på Field, som vi kommer att se om ett ögonblick.

Form.is_boundLink to this definition

Om du behöver skilja mellan bundna och obundna formulärinstanser vid körning, kontrollera värdet på formulärets attribut is_bound:

Python console
>>> f = ContactForm()
>>> f.is_bound
False
>>> f = ContactForm({"subject": "hello"})
>>> f.is_bound
True

Observera att om du skickar en tom ordbok skapas ett bundet formulär med tomma data:

Python console
>>> f = ContactForm({})
>>> f.is_bound
True

Om du har en bunden Form-instans och vill ändra data på något sätt, eller om du vill binda en obunden Form-instans till vissa data, skapar du en annan Form-instans. Det finns inget sätt att ändra data i en Form-instans. När en Form-instans har skapats bör du betrakta dess data som oföränderliga, oavsett om den har data eller inte.

Använda formulär för att validera dataLink to this heading

Form.clean()Link to this definition

Implementera en clean()-metod på din Form när du måste lägga till anpassad validering för fält som är beroende av varandra. Se Rengöring och validering av fält som är beroende av varandra för exempel på användning.

Form.is_valid()Link to this definition

Den primära uppgiften för ett Form-objekt är att validera data. Med en bunden Form-instans anropar du is_valid()-metoden för att köra validering och returnera en boolesk som anger om data var giltiga:

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "contact_email": "foo@example.com",
...     "urgent": True,
... }
>>> f = ContactForm(data)
>>> f.is_valid()
True

Let’s try with some invalid data. In this case, subject is blank (an error, because all fields are required by default) and contact_email is not a valid email address:

Python console
>>> data = {
...     "subject": "",
...     "message": "Hi there",
...     "contact_email": "invalid email address",
...     "urgent": True,
... }
>>> f = ContactForm(data)
>>> f.is_valid()
False
Form.errorsLink to this definition

Få tillgång till attributet errors för att få en ordlista med felmeddelanden:

Python console
>>> f.errors
{'subject': ['This field is required.'],
 'contact_email': ['Enter a valid email address.']}

I den här ordlistan är nycklarna fältnamnen och värdena listor med strängar som representerar felmeddelandena. Felmeddelandena lagras i listor eftersom ett fält kan ha flera felmeddelanden.

Du kan komma åt errors utan att först behöva anropa is_valid(). Formulärets data kommer att valideras första gången du antingen anropar is_valid() eller använder errors.

Valideringsrutinerna kommer bara att anropas en gång, oavsett hur många gånger du använder errors eller anropar is_valid(). Detta innebär att om valideringen har bieffekter, kommer dessa bieffekter bara att utlösas en gång.

Form.errors.as_data()Link to this definition

Returnerar ett dict som mappar fält till deras ursprungliga ValidationError-instanser.

Python console
>>> f.errors.as_data()
{'subject': [ValidationError(['This field is required.'])],
 'contact_email': [ValidationError(['Enter a valid email address.'])]}

Use this method anytime you need to identify an error by its code. This enables things like rewriting the error’s message or writing custom logic in a view when a given error is present. It can also be used to serialize the errors in a custom format (e.g. XML); for instance, as_json() relies on as_data().

Behovet av metoden as_data() beror på bakåtkompatibilitet. Tidigare förlorades ValidationError-instanser så snart deras renderade felmeddelanden lades till i Form.errors-ordlistan. Helst skulle Form.errors ha lagrat ValidationError-instanser och metoder med ett as_-prefix skulle kunna rendera dem, men det måste göras tvärtom för att inte bryta kod som förväntar sig renderade felmeddelanden i Form.errors.

Form.errors.as_json(escape_html=False)Link to this definition

Returns a string with the errors serialized as JSON.

Python console
>>> f.errors.as_json()
'{"subject": [{"message": "This field is required.", "code": "required"}],
 "contact_email": [{"message": "Enter a valid email address.", "code": "invalid"}]}'

Som standard escapar inte as_json() sin utdata. Om du använder den för något som AJAX-förfrågningar till en formulärvy där klienten tolkar svaret och infogar fel på sidan, vill du vara säker på att undkomma resultaten på klientsidan för att undvika risken för en cross-site scripting-attack. Du kan göra detta i JavaScript med element.textContent = errorText eller med jQuerys $(el).text(errorText) (snarare än dess .html()-funktion).

Om du av någon anledning inte vill använda escaping på klientsidan kan du också ställa in escape_html=True och felmeddelanden kommer att escapas så att du kan använda dem direkt i HTML.

Form.errors.get_json_data(escape_html=False)Link to this definition

Returns the errors as a dictionary suitable for serializing to JSON. Form.errors.as_json() returns serialized JSON, while this returns the error data before it’s serialized.

The escape_html parameter behaves as described in Form.errors.as_json().

Form.add_error(field, error)Link to this definition

Denna metod gör det möjligt att lägga till fel i specifika fält inom metoden Form.clean(), eller helt utanför formuläret, t.ex. från en vy.

Argumentet field är namnet på det fält som felen ska läggas till i. Om dess värde är None kommer felet att behandlas som ett icke-fältfel som returneras av Form.non_field_errors().

Argumentet error kan vara en sträng, eller helst en instans av ValidationError. Se Upphävande av ValidationError för bästa praxis vid definition av formulärfel.

Observera att Form.add_error() automatiskt tar bort det relevanta fältet från cleaned_data.

Form.has_error(field, code=None)Link to this definition

Denna metod returnerar en boolean som anger om ett fält har ett fel med en specifik fel-”kod”. Om code är None returneras True om fältet innehåller några fel alls.

För att kontrollera fel som inte är fält använder du NON_FIELD_ERRORS som parametern field.

Form.non_field_errors()Link to this definition

Den här metoden returnerar listan över fel från Form.errors som inte är associerade med ett visst fält. Detta inkluderar ValidationError som tas upp i Form.clean() och fel som läggs till med Form.add_error(None, "...").

Beteende för obundna formulärLink to this heading

Det är meningslöst att validera ett formulär utan data, men så här går det till när formuläret är obundet:

Python console
>>> f = ContactForm()
>>> f.is_valid()
False
>>> f.errors
{}

Initiala formvärdenLink to this heading

Form.initialLink to this definition

Använd initial för att ange det initiala värdet för formulärfält vid körning. Du kanske t.ex. vill fylla i fältet username med användarnamnet för den aktuella sessionen.

För att åstadkomma detta använder du argumentet initial till en Form. Detta argument, om det anges, bör vara en ordbok som mappar fältnamn till initiala värden. Inkludera bara de fält för vilka du anger ett initialt värde; det är inte nödvändigt att inkludera alla fält i ditt formulär. Exempelvis:

Python console
>>> f = ContactForm(initial={"subject": "Hi there!"})

Dessa värden visas endast för obundna formulär och de används inte som reservvärden om ett visst värde inte anges.

Om en Field definierar initial och du inkluderar initial när du instansierar Form, så kommer den senare initial att ha företräde. I det här exemplet anges initial både på fältnivå och på formulärinstansnivå, och den senare får företräde:

Python console
>>> from django import forms
>>> class CommentForm(forms.Form):
...     name = forms.CharField(initial="class")
...     url = forms.URLField()
...     comment = forms.CharField()
...
>>> f = CommentForm(initial={"name": "instance"}, auto_id=False)
>>> print(f)
<div>Name:<input type="text" name="name" value="instance" required></div>
<div>Url:<input type="url" name="url" required></div>
<div>Comment:<input type="text" name="comment" required></div>
Form.get_initial_for_field(field, field_name)Link to this definition

Returnerar de initiala uppgifterna för ett formulärfält. Den hämtar data från Form.initial om den finns, annars försöker den Field.initial. Kallbara värden utvärderas.

It is recommended to use BoundField.initial over get_initial_for_field() because BoundField.initial has a simpler interface. Also, unlike get_initial_for_field(), BoundField.initial caches its values. This is useful especially when dealing with callables whose return values can change (e.g. datetime.now or uuid.uuid4):

Python console
>>> import uuid
>>> class UUIDCommentForm(CommentForm):
...     identifier = forms.UUIDField(initial=uuid.uuid4)
...
>>> f = UUIDCommentForm()
>>> f.get_initial_for_field(f.fields["identifier"], "identifier")
UUID('972ca9e4-7bfe-4f5b-af7d-07b3aa306334')
>>> f.get_initial_for_field(f.fields["identifier"], "identifier")
UUID('1b411fab-844e-4dec-bd4f-e9b0495f04d0')
>>> # Using BoundField.initial, for comparison
>>> f["identifier"].initial
UUID('28a09c59-5f00-4ed9-9179-a3b074fa9c30')
>>> f["identifier"].initial
UUID('28a09c59-5f00-4ed9-9179-a3b074fa9c30')

Kontroll av vilka formulärdata som har ändratsLink to this heading

Form.has_changed()Link to this definition

Använd metoden has_changed() på ditt Form när du behöver kontrollera om formulärdata har ändrats från de ursprungliga data.

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "contact_email": "foo@example.com",
...     "urgent": True,
... }
>>> f = ContactForm(data, initial=data)
>>> f.has_changed()
False

När formuläret skickas in rekonstruerar vi det och tillhandahåller originaldata så att jämförelsen kan göras:

Python console
>>> f = ContactForm(request.POST, initial=data)
>>> f.has_changed()
True

has_changed() blir True om data från request.POST skiljer sig från vad som angavs i initial eller False annars. Resultatet beräknas genom att anropa Field.has_changed() för varje fält i formuläret.

Form.changed_dataLink to this definition

Attributet changed_data returnerar en lista med namnen på de fält vars värden i formulärets bundna data (vanligtvis request.POST) skiljer sig från vad som angavs i initial. Det returnerar en tom lista om inga data skiljer sig åt.

Python console
>>> f = ContactForm(request.POST, initial=data)
>>> f.changed_data
['subject', 'message']

Åtkomst till fälten från formuläretLink to this heading

Form.fieldsLink to this definition

Du kan komma åt fälten i Form-instansen från dess fields-attribut:

Python console
>>> for row in f.fields.values():
...     print(row)
...
<django.forms.fields.CharField object at 0x7ffaac632510>
<django.forms.fields.URLField object at 0x7ffaac632f90>
<django.forms.fields.CharField object at 0x7ffaac3aa050>
>>> f.fields["name"]
<django.forms.fields.CharField object at 0x7ffaac6324d0>

Du kan ändra fältet och BoundField i Form-instansen för att ändra hur det presenteras i formuläret:

Python console
>>> f.as_div().split("</div>")[0]
'<div><label for="id_subject">Subject:</label><input type="text" name="subject" maxlength="100" required id="id_subject">'
>>> f["subject"].label = "Topic"
>>> f.as_div().split("</div>")[0]
'<div><label for="id_subject">Topic:</label><input type="text" name="subject" maxlength="100" required id="id_subject">'

Tänk på att inte ändra attributet base_fields eftersom denna ändring kommer att påverka alla efterföljande ContactForm-instanser inom samma Python-process:

Python console
>>> f.base_fields["subject"].label_suffix = "?"
>>> another_f = ContactForm(auto_id=False)
>>> another_f.as_div().split("</div>")[0]
'<div><label for="id_subject">Subject?</label><input type="text" name="subject" maxlength="100" required id="id_subject">'

Tillgång till ”rena” dataLink to this heading

Form.cleaned_dataLink to this definition

Varje fält i en Form-klass ansvarar inte bara för att validera data utan också för att ”rensa” dem - normalisera dem till ett enhetligt format. Det här är en bra funktion eftersom det gör att data för ett visst fält kan matas in på många olika sätt och alltid resultera i ett enhetligt resultat.

Till exempel: normaliserar DateField indata till ett Python-objekt av typen datetime.date. Oavsett om du skickar en sträng i formatet '1994-07-15', ett datetime.date-objekt eller ett antal andra format, kommer DateField alltid att normalisera det till ett datetime.date-objekt så länge det är giltigt.

När du har skapat en Form-instans med en uppsättning data och validerat den, kan du komma åt de rena data via dess cleaned_data-attribut:

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "contact_email": "foo@example.com",
...     "urgent": True,
... }
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'subject': 'hello', 'message': 'Hi there', 'contact_email': 'foo@example.com', 'urgent': True}

Observera att alla textbaserade fält - t.ex. CharField eller EmailField - alltid omvandlar inmatningen till en sträng. Vi kommer att täcka kodningsimplikationerna senare i detta dokument.

Om dina data inte valideras innehåller ordlistan cleaned_data endast de giltiga fälten:

Python console
>>> data = {
...     "subject": "",
...     "message": "Hi there",
...     "contact_email": "invalid email address",
...     "urgent": True,
... }
>>> f = ContactForm(data)
>>> f.is_valid()
False
>>> f.cleaned_data
{'message': 'Hi there', 'urgent': True}

cleaned_data kommer alltid bara att innehålla en nyckel för fält som definieras i Form, även om du skickar extra data när du definierar Form. I det här exemplet skickar vi en massa extra fält till konstruktören ContactForm, men cleaned_data innehåller bara formulärets fält:

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "contact_email": "foo@example.com",
...     "urgent": True,
...     "extra_field_1": "foo",
...     "extra_field_2": "bar",
...     "extra_field_3": "baz",
... }
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data  # Doesn't contain extra_field_1, etc.
{'subject': 'hello', 'message': 'Hi there', 'contact_email': 'foo@example.com', 'urgent': True}

When the Form is valid, cleaned_data will include a key and value for all its fields, even if the data didn’t include a value for some optional fields. In this example, the data dictionary doesn’t include a value for the nickname field, but cleaned_data includes it, with an empty value:

Python console
>>> from django import forms
>>> class OptionalPersonForm(forms.Form):
...     first_name = forms.CharField()
...     last_name = forms.CharField()
...     nickname = forms.CharField(required=False)
...
>>> data = {"first_name": "John", "last_name": "Lennon"}
>>> f = OptionalPersonForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'first_name': 'John', 'last_name': 'Lennon', 'nickname': ''}

In this above example, the cleaned_data value for nickname is set to an empty string, because nickname is CharField, and CharFields treat empty values as an empty string. Each field type knows what its ”blank” value is – e.g., for DateField, it’s None instead of the empty string. For full details on each field’s behavior in this case, see the ”Empty value” note for each field in the Inbyggda Field-klasser section below.

Du kan skriva kod för att utföra validering för vissa formulärfält (baserat på deras namn) eller för formuläret som helhet (med hänsyn till kombinationer av olika fält). Mer information om detta finns i Validering av formulär och fält.

Utmatning av formulär som HTMLLink to this heading

Den andra uppgiften för ett Form-objekt är att rendera sig själv som HTML. För att göra det, print det:

Python console
>>> f = ContactForm()
>>> print(f)
<div><label for="id_subject">Subject:</label><input type="text" name="subject" maxlength="100" required id="id_subject"></div>
<div><label for="id_message">Message:</label><textarea name="message" cols="40" rows="10" required id="id_message"></textarea></div>
<div><label for="id_contact_email">Contact email:</label><input type="email" name="contact_email" maxlength="320" required id="id_contact_email"></div>
<div><label for="id_urgent">Urgent:</label><input type="checkbox" name="urgent" id="id_urgent"></div>

Om formuläret är bundet till data kommer HTML-utdata att innehålla dessa data på lämpligt sätt. Om ett fält t.ex. representeras av en <input type="text">, kommer data att finnas i attributet value. Om ett fält representeras av en <input type="checkbox">, kommer HTML-texten att innehålla checked om så är lämpligt:

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "contact_email": "foo@example.com",
...     "urgent": True,
... }
>>> f = ContactForm(data)
>>> print(f)
<div><label for="id_subject">Subject:</label><input type="text" name="subject" value="hello" maxlength="100" required id="id_subject"></div>
<div><label for="id_message">Message:</label><textarea name="message" cols="40" rows="10" required id="id_message">Hi there</textarea></div>
<div><label for="id_contact_email">Contact email:</label><input type="email" name="contact_email" value="foo@example.com" maxlength="320" required id="id_contact_email"></div>
<div><label for="id_urgent">Urgent:</label><input type="checkbox" name="urgent" id="id_urgent" checked></div>

Denna standardutskrift omsluter varje fält med en <div>. Lägg märke till följande:

  • För flexibilitetens skull innehåller utdata inte taggarna<form>``` och `</form> eller taggen ``<input type="submit">. Det är ditt jobb att göra det.

  • Varje fälttyp har en standard HTML-representation. CharField representeras av en <input type="text"> och EmailField av en <input type="email">. BooleanField(null=False) representeras av en <input type="checkbox">. Observera att detta bara är förnuftiga standardvärden; du kan ange vilken HTML som ska användas för ett visst fält genom att använda widgets, som vi förklarar strax.

  • HTML-namnet för varje tagg hämtas direkt från attributnamnet i klassen ”ContactForm”.

  • The text label for each field – e.g. 'Subject:', 'Message:' and 'Contact email:' is generated from the field name by converting all underscores to spaces and upper-casing the first letter. Again, note these are merely sensible defaults; you can also specify labels manually.

  • Varje textetikett omges av en HTML-tagg <label>, som pekar på lämpligt formulärfält via dess id. Dess id genereras i sin tur genom att fältnamnet kompletteras med 'id_. Attributen id och taggarna <label> inkluderas i utdata som standard, för att följa bästa praxis, men du kan ändra detta beteende.

  • Utdata använder HTML5-syntax, med <!DOCTYPE html> som mål. Exempelvis används booleska attribut som checked i stället för XHTML-stilen checked='checked'.

Även om <div> är standardutmatningsstilen när du skriver ut ett formulär kan du anpassa utmatningen genom att använda din egen formulärmall som kan ställas in för hela webbplatsen, per formulär eller per instans. Se återanvändbara-formulär-mallar.

Standard renderingLink to this heading

Standardrenderingen när du printar ett formulär använder följande metoder och attribut.

template_nameLink to this heading

Form.template_nameLink to this definition

Namnet på den mall som återges om formuläret omvandlas till en sträng, t.ex. via print(form) eller i en mall via {{ form }}.

Som standard en egenskap som returnerar värdet av renderingsprogrammets form_template_name. Du kan ställa in det som ett strängmallnamn för att åsidosätta det för en viss formulärklass.

render()Link to this heading

Form.render(template_name=None, context=None, renderer=None)Link to this definition

Renderingsmetoden anropas av __str__ samt metoderna Form.as_div(), Form.as_table(), Form.as_p() och Form.as_ul(). Alla argument är valfria och standardvärdena är:

Genom att skicka template_name kan du anpassa den mall som används för bara ett enda anrop.

get_context()Link to this heading

Form.get_context()Link to this definition

Returnerar mallkontexten för rendering av formuläret.

Den tillgängliga kontexten är:

  • ”Formulär”: Det bundna formuläret.

  • fält: Alla bundna fält, utom de dolda fälten.

  • hidden_fields: Alla dolda bundna fält.

  • fel: Alla formulärfel som inte är fältrelaterade eller som är relaterade till dolda fält.

template_name_labelLink to this heading

Form.template_name_labelLink to this definition

Den mall som används för att rendera ett fälts <label>, används vid anrop av BoundField.label_tag()/legend_tag(). Kan ändras per formulär genom att åsidosätta detta attribut eller mer generellt genom att åsidosätta standardmallen, se även Åsidosätta inbyggda formulärmallar.

UtmatningsstilarLink to this heading

Det rekommenderade tillvägagångssättet för att ändra formulärets utmatningsstil är att ange en anpassad formulärmall antingen för hela webbplatsen, per formulär eller per instans. Se Återanvändbara formulärmallar för exempel.

Följande hjälpfunktioner tillhandahålls för bakåtkompatibilitet och är en proxy till Form.render() som skickar ett visst värde för template_name.

Varje helper parar ihop en formulärmetod med ett attribut som anger det lämpliga mallnamnet.

as_div()Link to this heading

Form.template_name_divLink to this definition

Den mall som används av as_div(). Standard: 'django/forms/div.html'.

Form.as_div()Link to this definition

as_div() renderar formuläret som en serie av <div> element, där varje <div> innehåller ett fält, t.ex:

Python console
>>> f = ContactForm()
>>> f.as_div()

… gives HTML like:

Html
<div>
<label for="id_subject">Subject:</label>
<input type="text" name="subject" maxlength="100" required id="id_subject">
</div>
<div>
<label for="id_message">Message:</label>
<textarea name="message" cols="40" rows="10" required id="id_message"></textarea>
</div>
<div>
<label for="id_contact_email">Contact email:</label>
<input type="email" name="contact_email" required id="id_contact_email">
</div>
<div>
<label for="id_urgent">Urgent:</label>
<input type="checkbox" name="urgent" id="id_urgent">
</div>

as_p()Link to this heading

Form.template_name_pLink to this definition

Den mall som används av as_p(). Standard: 'django/forms/p.html'.

Form.as_p()Link to this definition

as_p() återger formuläret som en serie <p> taggar, där varje <p> innehåller ett fält:

Python console
>>> f = ContactForm()
>>> f.as_p()

… gives HTML like:

Html
<p><label for="id_subject">Subject:</label> <input type="text" name="subject" maxlength="100" required id="id_subject"></p>
<p><label for="id_message">Message:</label> <textarea name="message" cols="40" rows="10" required id="id_message"></textarea></p>
<p><label for="id_contact_email">Contact email:</label> <input type="email" name="contact_email" maxlength="320" required id="id_contact_email"></p>
<p><label for="id_urgent">Urgent:</label> <input type="checkbox" name="urgent" id="id_urgent"></p>

as_ul()Link to this heading

Form.template_name_ulLink to this definition

Den mall som används av as_ul(). Standard: 'django/forms/ul.html'.

Form.as_ul()Link to this definition

as_ul() renderar formuläret som en serie av <li> taggar, med varje <li> som innehåller ett fält. Den inkluderar *inte*<ul>``` eller `,</ul> att du kan ange HTML-attribut ``<ul> för flexibilitet:

Python console
>>> f = ContactForm()
>>> f.as_ul()

… gives HTML like:

Html
<li><label for="id_subject">Subject:</label> <input type="text" name="subject" maxlength="100" required id="id_subject"></li>
<li><label for="id_message">Message:</label> <textarea name="message" cols="40" rows="10" required id="id_message"></textarea></li>
<li><label for="id_contact_email">Contact email:</label> <input type="email" name="contact_email" maxlength="320" required id="id_contact_email"></li>
<li><label for="id_urgent">Urgent:</label> <input type="checkbox" name="urgent" id="id_urgent"></li>

as_table()Link to this heading

Form.template_name_tableLink to this definition

Den mall som används av as_table(). Standard: 'django/forms/table.html'.

Form.as_table()Link to this definition

as_table() återger formuläret som en HTML <table>:

Python console
>>> f = ContactForm()
>>> f.as_table()

… gives HTML like:

Html
<tr><th><label for="id_subject">Subject:</label></th><td><input type="text" name="subject" maxlength="100" required id="id_subject"></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><textarea name="message" cols="40" rows="10" required id="id_message"></textarea></td></tr>
<tr><th><label for="id_contact_email">Contact email:</label></th><td><input type="email" name="contact_email" maxlength="320" required id="id_contact_email"></td></tr>
<tr><th><label for="id_urgent">Urgent:</label></th><td><input type="checkbox" name="urgent" id="id_urgent"></td></tr>

Styling av nödvändiga eller felaktiga formulärraderLink to this heading

Form.error_css_classLink to this definition
Form.required_css_classLink to this definition

Det är ganska vanligt att formatera formulärrader och fält som är obligatoriska eller har fel. Du kanske till exempel vill presentera obligatoriska formulärrader i fetstil och markera fel i rött.

Klassen Form har ett par hooks som du kan använda för att lägga till class-attribut till obligatoriska rader eller till rader med fel: ställ in attributen Form.error_css_class och/eller Form.required_css_class:

Code
from django import forms


class ContactForm(forms.Form):
    error_css_class = "error"
    required_css_class = "required"

    # ... and the rest of your fields here

När du har gjort det kommer raderna att få klasserna "error" och/eller "required", efter behov. HTML kommer att se ut ungefär som:

Python console
>>> f = ContactForm(data)
>>> print(f)
<div class="required"><label for="id_subject" class="required">Subject:</label> ...
<div class="required"><label for="id_message" class="required">Message:</label> ...
<div class="required"><label for="id_contact_email" class="required">Contact email:</label> ...
<div><label for="id_urgent">Urgent:</label> ...
>>> f["subject"].label_tag()
<label class="required" for="id_subject">Subject:</label>
>>> f["subject"].legend_tag()
<legend class="required" for="id_subject">Subject:</legend>
>>> f["subject"].label_tag(attrs={"class": "foo"})
<label for="id_subject" class="foo required">Subject:</label>
>>> f["subject"].legend_tag(attrs={"class": "foo"})
<legend for="id_subject" class="foo required">Subject:</legend>

Du kan ytterligare modifiera återgivningen av formulärrader genom att använda en custom BoundField.

Konfigurera HTML-attributen id och taggarna <label> för formulärelementLink to this heading

Form.auto_idLink to this definition

Som standard inkluderar metoderna för formuläråtergivning:

  • HTML id-attribut på formulärelementen.

  • Motsvarande <label> taggar runt etiketterna. En HTML-tagg <label> anger vilken etikettext som är associerad med vilket formulärelement. Denna lilla förbättring gör formulär mer användbara och mer tillgängliga för hjälpmedel. Det är alltid en god idé att använda <label>-taggar.

The id attribute values are generated by prepending id_ to the form field names. This behavior is configurable, though, if you want to change the id convention or remove HTML id attributes and <label> tags entirely.

Använd argumentet auto_id i konstruktören Form för att styra beteendet för id och etiketter. Detta argument måste vara True, False eller en sträng.

Om auto_id är False, kommer formuläret inte att innehålla <label> taggar eller id attribut:

Python console
>>> f = ContactForm(auto_id=False)
>>> print(f)
<div>Subject:<input type="text" name="subject" maxlength="100" required></div>
<div>Message:<textarea name="message" cols="40" rows="10" required></textarea></div>
<div>Contact email:<input type="email" name="contact_email" required></div>
<div>Urgent:<input type="checkbox" name="urgent"></div>

Om auto_id är inställt på True, kommer formulärutdata att inkludera <label> taggar och använda fältnamnet som id för varje formulärfält:

Python console
>>> f = ContactForm(auto_id=True)
>>> print(f)
<div><label for="subject">Subject:</label><input type="text" name="subject" maxlength="100" required id="subject"></div>
<div><label for="message">Message:</label><textarea name="message" cols="40" rows="10" required id="message"></textarea></div>
<div><label for="contact_email">Contact email:</label><input type="email" name="contact_email" required id="contact_email"></div>
<div><label for="urgent">Urgent:</label><input type="checkbox" name="urgent" id="urgent"></div>

Om auto_id är inställd på en sträng som innehåller formattecknet '%s', kommer formulärutmatningen att innehålla <label> taggar och generera id attribut baserat på formatsträngen. Till exempel:, för en formatsträng 'field_%s', kommer ett fält med namnet subject att få id-värdet 'field_subject'. Vi fortsätter med vårt exempel:

Python console
>>> f = ContactForm(auto_id="id_for_%s")
>>> print(f)
<div><label for="id_for_subject">Subject:</label><input type="text" name="subject" maxlength="100" required id="id_for_subject"></div>
<div><label for="id_for_message">Message:</label><textarea name="message" cols="40" rows="10" required id="id_for_message"></textarea></div>
<div><label for="id_for_contact_email">Contact email:</label><input type="email" name="contact_email" required id="id_for_contact_email"></div>
<div><label for="id_for_urgent">Urgent:</label><input type="checkbox" name="urgent" id="id_for_urgent"></div>

Om auto_id sätts till något annat sant värde - t.ex. en sträng som inte innehåller %s - kommer biblioteket att agera som om auto_id är True.

Som standard är auto_id inställd på strängen 'id_%s'.

Form.label_suffixLink to this definition

En översättningsbar sträng (standard är ett kolon (:) på engelska) som läggs till efter ett etikettnamn när ett formulär renderas.

Det är möjligt att anpassa det tecknet, eller utelämna det helt, med hjälp av parametern label_suffix:

Python console
>>> f = ContactForm(auto_id="id_for_%s", label_suffix="")
>>> print(f)
<div><label for="id_for_subject">Subject</label><input type="text" name="subject" maxlength="100" required id="id_for_subject"></div>
<div><label for="id_for_message">Message</label><textarea name="message" cols="40" rows="10" required id="id_for_message"></textarea></div>
<div><label for="id_for_contact_email">Contact email</label><input type="email" name="contact_email" required id="id_for_contact_email"></div>
<div><label for="id_for_urgent">Urgent</label><input type="checkbox" name="urgent" id="id_for_urgent"></div>
>>> f = ContactForm(auto_id="id_for_%s", label_suffix=" ->")
>>> print(f)
<div><label for="id_for_subject">Subject -&gt;</label><input type="text" name="subject" maxlength="100" required id="id_for_subject"></div>
<div><label for="id_for_message">Message -&gt;</label><textarea name="message" cols="40" rows="10" required id="id_for_message"></textarea></div>
<div><label for="id_for_contact_email">Contact email -&gt;</label><input type="email" name="contact_email" required id="id_for_contact_email"></div>
<div><label for="id_for_urgent">Urgent -&gt;</label><input type="checkbox" name="urgent" id="id_for_urgent"></div>

Observera att etikettens suffix endast läggs till om det sista tecknet i etiketten inte är ett skiljetecken (på engelska är det ., !, ? eller :).

Fält kan också definiera sina egna label_suffix. Detta kommer att ha företräde framför Form.label_suffix. Suffixet kan också åsidosättas vid körning med hjälp av parametern label_suffix till label_tag()/ legend_tag().

Form.use_required_attributeLink to this definition

När den är inställd på True (standard) kommer obligatoriska formulärfält att ha HTML-attributet required.

Formsets </topics/forms/formsets>` instansiera formulär med use_required_attribute=False för att undvika felaktig webbläsarvalidering när du lägger till och tar bort formulär från en formset.

Konfigurera återgivningen av widgetar i ett formulärLink to this heading

Form.default_rendererLink to this definition

Specifies the renderer to use for the form. Defaults to None which means to use the default renderer specified by the FORM_RENDERER setting.

Du kan ange detta som ett klassattribut när du deklarerar ditt formulär eller använda argumentet renderer i Form.__init__(). Till exempel:

Code
from django import forms


class MyForm(forms.Form):
    default_renderer = MyRenderer()

eller:

Code
form = MyForm(renderer=MyRenderer())

Anmärkningar om fältbeställningLink to this heading

In the as_p(), as_ul() and as_table() shortcuts, the fields are displayed in the order in which you define them in your form class. For example, in the ContactForm example, the fields are defined in the order subject, message, contact_email, urgent. To reorder the HTML output, change the order in which those fields are listed in the class.

Det finns flera andra sätt att skräddarsy beställningen:

Form.field_orderLink to this definition

Som standard är Form.field_order=None, vilket innebär att den ordning som du definierar fälten i formulärklassen behålls. Om field_order är en lista med fältnamn ordnas fälten enligt listan och återstående fält läggs till enligt standardordningen. Okända fältnamn i listan ignoreras. Detta gör det möjligt att inaktivera ett fält i en underklass genom att ställa in det på None utan att behöva omdefiniera ordningen.

Du kan också använda argumentet Form.field_order till en Form för att åsidosätta fältordningen. Om en Form definierar field_order och du inkluderar field_order när du instansierar Form, så kommer den senare field_order att ha företräde.

Form.order_fields(field_order)Link to this definition

Du kan omorganisera fälten när som helst med hjälp av order_fields() med en lista över fältnamn som i field_order.

Hur fel visasLink to this heading

Om du renderar ett bundet Form-objekt, kommer renderingen automatiskt att köra formulärets validering om det inte redan har skett, och HTML-utmatningen kommer att innehålla valideringsfelen som en <ul class="errorlist">.

Följande:

Python console
>>> data = {
...     "subject": "",
...     "message": "Hi there",
...     "contact_email": "invalid email address",
...     "urgent": True,
... }
>>> ContactForm(data).as_div()

… gives HTML like:

Html
<div>
  <label for="id_subject">Subject:</label>
  <ul class="errorlist" id="id_subject_error"><li>This field is required.</li></ul>
  <input type="text" name="subject" maxlength="100" required aria-invalid="true" aria-describedby="id_subject_error" id="id_subject">
</div>
<div>
  <label for="id_message">Message:</label>
  <textarea name="message" cols="40" rows="10" required id="id_message">Hi there</textarea>
</div>
<div>
  <label for="id_contact_email">Contact email:</label>
  <ul class="errorlist" id="id_contact_email_error"><li>Enter a valid email address.</li></ul>
  <input type="email" name="contact_email" value="invalid email address" maxlength="320" required aria-invalid="true" aria-describedby="id_contact_email_error" id="id_contact_email">
</div>
<div>
    <label for="id_urgent">Urgent:</label>
    <input type="checkbox" name="urgent" id="id_urgent" checked>
</div>

Djangos standardformulärsmallar kommer att associera valideringsfel med deras inmatning genom att använda HTML-attributet aria-describedby när fältet har ett auto_id och en anpassad aria-describedby inte tillhandahålls. Om ett anpassat aria-describedby anges när widgeten definieras kommer detta att åsidosätta standardvärdet.

Om widgeten återges i en <fieldset> läggs aria-describedby till i detta element, annars läggs det till i widgetens HTML-element (t.ex. <input>).

Anpassa formatet för fellistanLink to this heading

class ErrorList(initlist=None, error_class=None, renderer=None, field_id=None)Link to this definition

Som standard använder formulär django.forms.utils.ErrorList för att formatera valideringsfel. ErrorList är ett listliknande objekt där initlist är listan över fel. Dessutom har denna klass följande attribut och metoder.

error_classLink to this definition

De CSS-klasser som ska användas vid rendering av fellistan. Alla angivna klasser läggs till i standardklassen errorlist.

rendererLink to this definition

Specifies the renderer to use for ErrorList. Defaults to None which means to use the default renderer specified by the FORM_RENDERER setting.

field_idLink to this definition

Ett id för det fält som felen avser. Detta gör att ett HTML-attribut id kan läggas till i felmallen och är användbart för att associera felen med fältet. Standardmallen använder formatet id="{{ field_id }}_error" och ett värde tillhandahålls av Form.add_error() med hjälp av fältets auto_id.

template_nameLink to this definition

Namnet på den mall som används vid anrop av __str__ eller render(). Som standard är detta 'django/forms/errors/list/default.html' som är en proxy för mallen 'ul.html'.

template_name_textLink to this definition

Namnet på den mall som används vid anrop av as_text(). Som standard är detta 'django/forms/errors/list/text.html'. Den här mallen återger felen som en lista med punkter.

template_name_ulLink to this definition

Namnet på den mall som används vid anrop av as_ul(). Som standard är detta 'django/forms/errors/list/ul.html'. Denna mall återger felen i <li> taggar med en omslags <ul> med CSS-klasserna som definieras av error_class.

get_context()Link to this definition

Returnerar kontext för återgivning av fel i en mall.

Den tillgängliga kontexten är:

  • errors : En lista över fel.

  • error_class : En sträng med CSS-klasser.

render(template_name=None, context=None, renderer=None)Link to this definition

Renderingsmetoden anropas av __str__ samt av metoden as_ul`().

Alla argument är valfria och kommer att användas som standard:

as_text()Link to this definition

Renderar fellistan med hjälp av den mall som definieras av template_name_text.

as_ul()Link to this definition

Renderar fellistan med hjälp av den mall som definieras av template_name_ul.

Om du vill anpassa återgivningen av fel kan detta uppnås genom att åsidosätta attributet template_name eller mer allmänt genom att åsidosätta standardmallen, se även Åsidosätta inbyggda formulärmallar.

Mer detaljerad utdataLink to this heading

Metoderna as_p(), as_ul() och as_table() är genvägar - de är inte det enda sättet som ett formulärobjekt kan visas på.

class BoundFieldLink to this definition

Används för att visa HTML eller åtkomstattribut för ett enskilt fält i en Form-instans.

Metoden __str__() för detta objekt visar HTML för detta fält.

Du kan använda Form.bound_field_class och Field.bound_field_class för att ange en annan BoundField-klass per formulär respektive per fält.

Se Anpassa BoundField för exempel på åsidosättande av en BoundField.

Om du vill hämta ett enskilt BoundField använder du syntaxen för ordboksuppslagning i formuläret med fältets namn som nyckel:

Python console
>>> form = ContactForm()
>>> print(form["subject"])
<input type="text" name="subject" maxlength="100" required id="id_subject">

För att hämta alla BoundField-objekt, iterera formuläret:

Python console
>>> form = ContactForm()
>>> for boundfield in form:
...     print(boundfield)
...
<input type="text" name="subject" maxlength="100" required id="id_subject">
<textarea name="message" cols="40" rows="10" required id="id_message"></textarea>
<input type="email" name="contact_email" maxlength="320" required id="id_contact_email">
<input type="checkbox" name="urgent" id="id_urgent">

Den fältspecifika utmatningen följer formulärobjektets inställning auto_id:

Python console
>>> f = ContactForm(auto_id=False)
>>> print(f["message"])
<textarea name="message" cols="40" rows="10" required></textarea>
>>> f = ContactForm(auto_id="id_%s")
>>> print(f["message"])
<textarea name="message" cols="40" rows="10" required id="id_message"></textarea>

Attribut för BoundFieldLink to this heading

BoundField.aria_describedbyLink to this definition

Returnerar en aria-describedby-referens för att associera ett fält med dess hjälptext och fel. Returnerar None om aria-describedby är inställt i Widget.attrs för att bevara det användardefinierade attributet när formuläret renderas.

BoundField.auto_idLink to this definition

HTML ID-attributet för denna BoundField. Returnerar en tom sträng om Form.auto_id är False.

BoundField.dataLink to this definition

Denna egenskap returnerar data för denna BoundField som extraherats av widgetens value_from_datadict()-metod, eller None om den inte gavs:

Python console
>>> unbound_form = ContactForm()
>>> print(unbound_form["subject"].data)
None
>>> bound_form = ContactForm(data={"subject": "My Subject"})
>>> print(bound_form["subject"].data)
My Subject
BoundField.errorsLink to this definition

Ett listliknande objekt som visas som en HTML <ul class="errorlist"> när det skrivs ut:

Python console
>>> data = {"subject": "hi", "message": "", "contact_email": "", "urgent": ""}
>>> f = ContactForm(data, auto_id=False)
>>> print(f["message"])
<input type="text" name="message" required aria-invalid="true">
>>> f["message"].errors
['This field is required.']
>>> print(f["message"].errors)
<ul class="errorlist"><li>This field is required.</li></ul>
>>> f["subject"].errors
[]
>>> print(f["subject"].errors)

>>> str(f["subject"].errors)
''

Vid rendering av ett fält med fel kommer aria-invalid="true" att ställas in på fältets widget för att indikera att det finns ett fel för skärmläsaranvändare.

BoundField.fieldLink to this definition

Formulärets Field-instans från den formulärklass som denna BoundField omsluter.

BoundField.formLink to this definition

Den Form-instans som denna BoundField är bunden till.

BoundField.help_textLink to this definition

Fältets help_text.

BoundField.html_nameLink to this definition

Det namn som kommer att användas i widgetens HTML-attribut name. Det tar hänsyn till formuläret prefix.

BoundField.id_for_labelLink to this definition

Använd den här egenskapen för att återge fältets ID. Till exempel: om du manuellt konstruerar en <label> i din mall (trots att label_tag()/legend_tag() gör detta åt dig):

Django template
<label for="{{ form.my_field.id_for_label }}">...</label>{{ my_field }}

Som standard kommer detta att vara fältets namn med prefixet id_ (”id_my_field” i exemplet ovan). Du kan ändra ID genom att ställa in attrs på fältets widget. Till exempel:, om du deklarerar ett fält så här:

Code
my_field = forms.CharField(widget=forms.TextInput(attrs={"id": "myFIELD"}))

och med hjälp av mallen ovan, skulle rendera något liknande:

Html
<label for="myFIELD">...</label><input id="myFIELD" type="text" name="my_field" required>
BoundField.initialLink to this definition

Använd BoundField.initial för att hämta initialdata för ett formulärfält. Den hämtar data från Form.initial om den finns, annars försöker den Field.initial. Kallbara värden utvärderas. Se Initiala formvärden för fler exempel.

BoundField.initial cachar sitt returvärde, vilket är användbart särskilt när man har att göra med anropbara filer vars returvärden kan ändras (t.ex. datetime.now eller uuid.uuid4):

Python console
>>> from datetime import datetime
>>> class DatedCommentForm(CommentForm):
...     created = forms.DateTimeField(initial=datetime.now)
...
>>> f = DatedCommentForm()
>>> f["created"].initial
datetime.datetime(2021, 7, 27, 9, 5, 54)
>>> f["created"].initial
datetime.datetime(2021, 7, 27, 9, 5, 54)

Using BoundField.initial is recommended over get_initial_for_field().

BoundField.is_hiddenLink to this definition

Returnerar True om widgeten i denna BoundField är dold.

BoundField.labelLink to this definition

Fältets label. Detta används i label_tag()/legend_tag().

BoundField.nameLink to this definition

Namnet på detta fält i formuläret:

Python console
>>> f = ContactForm()
>>> print(f["subject"].name)
subject
>>> print(f["message"].name)
message
BoundField.template_nameLink to this definition

Namnet på den mall som återges med BoundField.as_field_group().

En egenskap som returnerar värdet av template_name om det är inställt på annat sätt field_template_name.

BoundField.use_fieldsetLink to this definition

Returnerar värdet på attributet use_fieldset för denna BoundField-widget.

BoundField.widget_typeLink to this definition

Returnerar det gemena klassnamnet på det omslutna fältets widget, med eventuella efterföljande input eller widget borttagna. Detta kan användas när man bygger formulär där layouten är beroende av widget-typen. Exempelvis:

Django template
{% for field in form %}
    {% if field.widget_type == 'checkbox' %}
        # render one way
    {% else %}
        # render another way
    {% endif %}
{% endfor %}

Metoder för BoundFieldLink to this heading

BoundField.as_field_group()Link to this definition

Renderar fältet med hjälp av BoundField.render() med standardvärden som renderar BoundField, inklusive dess etikett, hjälptext och fel med hjälp av mallens template_name om den är inställd annars field_template_name

BoundField.as_hidden(attrs=None, **kwargs)Link to this definition

Returnerar en HTML-sträng för att representera detta som en <input type="hidden">.

**kwargs skickas till as_widget().

Denna metod används främst internt. Du bör använda en widget istället.

BoundField.as_widget(widget=None, attrs=None, only_initial=False)Link to this definition

Renders the field by rendering the passed widget, adding any HTML attributes passed as attrs. If no widget is specified, then the field’s default widget will be used.

only_initial används av Django internals och bör inte ställas in explicit.

BoundField.css_classes(extra_classes=None)Link to this definition

När du använder Djangos renderingsgenvägar används CSS-klasser för att ange obligatoriska formulärfält eller fält som innehåller fel. Om du manuellt renderar ett formulär kan du komma åt dessa CSS-klasser med hjälp av metoden css_classes:

Python console
>>> f = ContactForm(data={"message": ""})
>>> f["message"].css_classes()
'required'

Om du vill tillhandahålla ytterligare klasser utöver de fel- och required-klasser som kan krävas, kan du ange dessa klasser som ett argument:

Python console
>>> f = ContactForm(data={"message": ""})
>>> f["message"].css_classes("foo bar")
'foo bar required'
BoundField.get_context()Link to this definition

Returnerar mallkontexten för rendering av fältet. Den tillgängliga kontexten är field som är instansen för det bundna fältet.

BoundField.label_tag(contents=None, attrs=None, label_suffix=None, tag=None)Link to this definition

Skapar en etikett för formulärfältet med hjälp av den mall som anges av Form.template_name_label.

Den tillgängliga kontexten är:

  • field: Denna instans av BoundField.

  • innehåll: Som standard en konkatenerad sträng av BoundField.label och Form.label_suffix (eller Field.label_suffix, om inställt). Detta kan åsidosättas med argumenten contents och label_suffix.

  • attrs: En dict som innehåller for, Form.required_css_class och id. id genereras av fältets widget attrs eller BoundField.auto_id. Ytterligare attribut kan anges med argumentet attrs.

  • use_tag: En boolean som är True om etiketten har ett id. Om False utelämnas taggen i standardmallen.

  • tag: En valfri sträng för att anpassa taggen, standard är label.

För att separat rendera etikett-taggen för ett formulärfält kan du anropa dess metod label_tag():

Python console
>>> f = ContactForm(data={"message": ""})
>>> print(f["message"].label_tag())
<label for="id_message">Message:</label>

Om du vill anpassa renderingen kan du göra det genom att åsidosätta attributet Form.template_name_label eller mer allmänt genom att åsidosätta standardmallen, se även Åsidosätta inbyggda formulärmallar.

BoundField.legend_tag(contents=None, attrs=None, label_suffix=None)Link to this definition

Anropar label_tag() med tag='legend' för att rendera etiketten med <legend> taggar. Detta är användbart vid rendering av radio och flera kryssrutor widgets där <legend> kan vara mer lämpligt än en <label>.

BoundField.render(template_name=None, context=None, renderer=None)Link to this definition

Renderingsmetoden anropas av as_field_group. Alla argument är valfria och används som standard:

Genom att skicka template_name kan du anpassa den mall som används för bara ett enda anrop.

BoundField.value()Link to this definition

Använd den här metoden för att återge fältets råvärde så som det skulle återges av en Widget:

Python console
>>> initial = {"subject": "welcome"}
>>> unbound_form = ContactForm(initial=initial)
>>> bound_form = ContactForm(data={"subject": "hi"}, initial=initial)
>>> print(unbound_form["subject"].value())
welcome
>>> print(bound_form["subject"].value())
hi

Anpassa BoundFieldLink to this heading

Form.bound_field_classLink to this definition

Definiera en anpassad BoundField-klass som ska användas när formuläret renderas. Detta har företräde framför BaseRenderer.bound_field_class på projektnivå (tillsammans med en anpassad FORM_RENDERER), men kan åsidosättas av Field.bound_field_class på fältnivå.

Om den inte definieras som en klassvariabel kan bound_field_class ställas in via argumentet bound_field_class i konstruktören Form eller Field.

For compatibility reasons, a custom form field can still override Field.get_bound_field() to use a custom class, though any of the previous options are preferred.

Du kanske vill använda en anpassad BoundField om du behöver komma åt ytterligare information om ett formulärfält i en mall och det inte räcker att använda en underklass av Field.

Om du till exempel har en GPSCoordinatesField och vill kunna få tillgång till ytterligare information om koordinaterna i en mall, kan detta implementeras enligt följande:

Code
class GPSCoordinatesBoundField(BoundField):
    @property
    def country(self):
        """
        Return the country the coordinates lie in or None if it can't be
        determined.
        """
        value = self.value()
        if value:
            return get_country_from_coordinates(value)
        else:
            return None


class GPSCoordinatesField(Field):
    bound_field_class = GPSCoordinatesBoundField

Nu kan du få tillgång till landet i en mall med {{ form.coordinates.country }}.

Du kanske också vill anpassa standardrenderingen av formulärfältsmallen. Du kan t.ex. åsidosätta BoundField.label_tag() för att lägga till en anpassad klass:

Code
class StyledLabelBoundField(BoundField):
    def label_tag(self, contents=None, attrs=None, label_suffix=None, tag=None):
        attrs = attrs or {}
        attrs["class"] = "wide"
        return super().label_tag(contents, attrs, label_suffix, tag)


class UserForm(forms.Form):
    bound_field_class = StyledLabelBoundField
    name = CharField()

Detta skulle uppdatera standardrenderingen av formuläret:

Python console
>>> f = UserForm()
>>> print(f["name"].label_tag)
<label for="id_name" class="wide">Name:</label>

För att lägga till en CSS-klass till det omslutande HTML-elementet för alla fält kan en BoundField åsidosättas för att returnera en annan samling CSS-klasser:

Code
class WrappedBoundField(BoundField):
    def css_classes(self, extra_classes=None):
        parent_css_classes = super().css_classes(extra_classes)
        return f"field-class {parent_css_classes}".strip()


class UserForm(forms.Form):
    bound_field_class = WrappedBoundField
    name = CharField()

Detta skulle uppdatera formulärets rendering enligt följande:

Python console
>>> f = UserForm()
>>> print(f)
<div class="field-class"><label for="id_name">Name:</label><input type="text" name="name" required id="id_name"></div>

Alternativt, för att åsidosätta klassen BoundField på projektnivå, kan BaseRenderer.bound_field_class definieras på en anpassad FORM_RENDERER:

mysite/renderers.py
Python
from django.forms.renderers import DjangoTemplates

from .forms import CustomBoundField


class CustomRenderer(DjangoTemplates):
    bound_field_class = CustomBoundField
settings.py
Python
FORM_RENDERER = "mysite.renderers.CustomRenderer"

Binder uppladdade filer till ett formulärLink to this heading

Att hantera formulär som har fälten FileField och ImageField är lite mer komplicerat än ett vanligt formulär.

För det första, för att ladda upp filer måste du se till att ditt <form> element korrekt definierar enctype som "multipart/form-data":

Html
<form enctype="multipart/form-data" method="post" action="/foo/">

För det andra måste du binda filinformationen när du använder formuläret. Fildata hanteras separat från normal formulärdata, så när ditt formulär innehåller en FileField och ImageField måste du ange ett andra argument när du binder ditt formulär. Så om vi utökar vårt ContactForm så att det innehåller en ImageField som heter mugshot, måste vi binda de fildata som innehåller mugshot-bilden:

Python console
# Bound form with an image field
>>> from django.core.files.uploadedfile import SimpleUploadedFile
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "contact_email": "foo@example.com",
...     "urgent": True,
... }
>>> file_data = {"mugshot": SimpleUploadedFile("face.jpg", b"file data")}
>>> f = ContactFormWithMugshot(data, file_data)

I praktiken anger du vanligtvis request.FILES som källa för fildata (precis som du använder request.POST som källa för formulärdata):

Python console
# Bound form with an image field, data from the request
>>> f = ContactFormWithMugshot(request.POST, request.FILES)

Att konstruera ett obundet formulär är samma sak som alltid - utelämna både formulärdata och fildata:

Python console
# Unbound form with an image field
>>> f = ContactFormWithMugshot()

Testning av formulär med flera delarLink to this heading

Form.is_multipart()Link to this definition

Om du skriver återanvändbara vyer eller mallar kanske du inte vet i förväg om ditt formulär är ett flerdelat formulär eller inte. Metoden is_multipart() talar om för dig om formuläret kräver multipart-kodning för inlämning:

Python console
>>> f = ContactFormWithMugshot()
>>> f.is_multipart()
True

Här är ett exempel på hur du kan använda detta i en mall:

Django template
{% if form.is_multipart %}
    <form enctype="multipart/form-data" method="post" action="/foo/">
{% else %}
    <form method="post" action="/foo/">
{% endif %}
{{ form }}
</form>

Underklassificering av formulärLink to this heading

Om du har flera Form-klasser som delar fält kan du använda subklassning för att ta bort redundans.

När du subklassar en anpassad Form-klass kommer den resulterande subklassen att innehålla alla fält i den eller de överordnade klasserna, följt av de fält som du definierar i subklassen.

In this example, ContactFormWithDepartment contains all the fields from ContactForm, plus an additional field, department. The ContactForm fields are ordered first:

Python console
>>> class ContactFormWithDepartment(ContactForm):
...     department = forms.CharField()
...
>>> f = ContactFormWithDepartment(auto_id=False)
>>> print(f)
<div>Subject:<input type="text" name="subject" maxlength="100" required></div>
<div>Message:<textarea name="message" cols="40" rows="10" required></textarea></div>
<div>Contact email:<input type="email" name="contact_email" required></div>
<div>Urgent:<input type="checkbox" name="urgent"></div>
<div>Department:<input type="text" name="department" required></div>

Det är möjligt att subklassa flera formulär och behandla formulär som mixins. I det här exemplet är BeatleForm en underklass till både PersonForm och InstrumentForm (i den ordningen), och dess fältlista innehåller fälten från de överordnade klasserna:

Python console
>>> from django import forms
>>> class PersonForm(forms.Form):
...     first_name = forms.CharField()
...     last_name = forms.CharField()
...
>>> class InstrumentForm(forms.Form):
...     instrument = forms.CharField()
...
>>> class BeatleForm(InstrumentForm, PersonForm):
...     haircut_type = forms.CharField()
...
>>> b = BeatleForm(auto_id=False)
>>> print(b)
<div>First name:<input type="text" name="first_name" required></div>
<div>Last name:<input type="text" name="last_name" required></div>
<div>Instrument:<input type="text" name="instrument" required></div>
<div>Haircut type:<input type="text" name="haircut_type" required></div>

Det är möjligt att deklarativt ta bort ett Field som ärvts från en överordnad klass genom att ställa in namnet på fältet till None i underklassen. Ett exempel:

Python console
>>> from django import forms

>>> class ParentForm(forms.Form):
...     name = forms.CharField()
...     age = forms.IntegerField()
...

>>> class ChildForm(ParentForm):
...     name = None
...

>>> list(ChildForm().fields)
['age']

Prefix för formerLink to this heading

Form.prefixLink to this definition

Du kan lägga in flera Django formulär i en <form> tagg. För att ge varje Form sitt eget namnområde, använd nyckelordsargumentet prefix:

Python console
>>> mother = PersonForm(prefix="mother")
>>> father = PersonForm(prefix="father")
>>> print(mother)
<div><label for="id_mother-first_name">First name:</label><input type="text" name="mother-first_name" required id="id_mother-first_name"></div>
<div><label for="id_mother-last_name">Last name:</label><input type="text" name="mother-last_name" required id="id_mother-last_name"></div>
>>> print(father)
<div><label for="id_father-first_name">First name:</label><input type="text" name="father-first_name" required id="id_father-first_name"></div>
<div><label for="id_father-last_name">Last name:</label><input type="text" name="father-last_name" required id="id_father-last_name"></div>

Prefixet kan också anges på formulärklassen:

Python console
>>> class PersonForm(forms.Form):
...     ...
...     prefix = "person"
...