Foirmeacha a chruthú ó shamhlLink to this heading

SamhlfhoirmeLink to this heading

class ModelFormLink to this definition

Má tá aip faoi thiomáint bunachar sonraí á thógáil agat, is dócha go mbeidh foirmeacha agat a léarscálann go dlúth do mhúnlaí Django. Mar shampla, b'fhéidir go mbeadh samhail ``BlogComment ``agat, agus ba mhaith leat foirm a chruthú a ligeann do dhaoine tuairimí a chur isteach. Sa chás seo, bheadh sé iomarcach na cineálacha réimse i d'fhoirm a shainiú, toisc go bhfuil na réimsí i do mhúnla sainmhínithe agat cheana féin.

Ar an gcúis seo, soláthraíonn Django rang cúntóra a ligeann duit rang ``Form ``a chruthú ó mhúnla Django.

Mar shampla:

Python console
>>> from django.forms import ModelForm
>>> from myapp.models import Article

# Create the form class.
>>> class ArticleForm(ModelForm):
...     class Meta:
...         model = Article
...         fields = ["pub_date", "headline", "content", "reporter"]
...

# Creating a form to add an article.
>>> form = ArticleForm()

# Creating a form to change an existing article.
>>> article = Article.objects.get(pk=1)
>>> form = ArticleForm(instance=article)

Cineálacha réimseLink to this heading

Beidh réimse foirme ag an rang Foirm a ghintear do gach réimse samhail a shonraítear, san ord a shonraítear sa tréith ``réimsí réimsí `réimsí `réimsí `.

Tá réimse foirme réamhshocraithe comhfhreagrach ag gach réimse samhail Mar shampla, léirítear charfield ar mhúnla mar charfield` ar fhoirm. Léirítear samhail `ManyTomanyField mar MultiplechoiceField. Seo an liosta iomlán na tiontaithe:

Réimse múnla

Réimse foirm

AutoField

Ní léirítear san fhoirm

BigAutoField

Ní léirítear san fhoirm

BigIntegerField

IntegerField with min_value set to -9223372036854775808 and max_value set to 9223372036854775807.

BinaryField

CharField, if editable is set to True on the model field, otherwise not represented in the form.

BooleanField

BooleanField, or NullBooleanField if null=True.

CharField

CharField with max_length set to the model field's max_length and empty_value set to None if null=True.

DateField

DateField

DateTimeField

DateTimeField

DecimalField

DecimalField

DurationField

DurationField

EmailField

EmailField

FileField

FileField

FilePathField

FilePathField

FloatField

FloatField

ForeignKey

ModelChoiceField (see below)

ImageField

ImageField

IntegerField

IntegerField

Ipaddressfield

Ipaddressfield

GenericIPAddressField

GenericIPAddressField

JSONField

JSONField

ManyToManyField

ModelMultipleChoiceField (see below)

PositiveBigIntegerField

IntegerField

PositiveIntegerField

IntegerField

PositiveSmallIntegerField

IntegerField

SlugField

SlugField

SmallAutoField

Ní léirítear san fhoirm

SmallIntegerField

IntegerField

TextField

CharField with widget=forms.Textarea

TimeField

TimeField

URLField

URLField

UUIDField

UUIDField

Mar a d'fhéadfá a bheith ag súil leis, is cásanna speisialta iad na cineálacha réimse samhail ForeignKey agus ManyTomanyField:

  • Léirítear ForeignKey le Django.Forms.ModelChoiceField, ar ChoiceField` is samhail QuerySet iad a roghanna.

  • Léirítear ManyTomanyField le Django.Forms.ModelMultipleChoiceField, ar MultipleChoiceField` is samhail QuerySet iad a roghanna.

Ina theannta sin, tá tréithe socraithe mar seo a leanas ag gach réimse foirme a ghintear

  • Má tá Blank=True sa réimse samhail, ansin socraítear riachtan go False ar an réimse foirme. Seachas sin, Required=True.

  • Socraítear lip réimse an fhoirme go verbose_name an réimse samhail, agus an chéad charachtar a chaipitliú.

  • Socraítear help_text réimse an fhoirme go help_text sa réimse samhail.

  • Má tá roghanna ``socraithe sa réimse samhail, ansin socraítear ``giuirléid réimse an fhoirme go Roghnaigh ``, agus roghanna a thagann ó `roghanna réimse an mhúnla. De ghnáth beidh an rogha bán a roghnaítear de réir réamhshocraithe san áireamh sna roghanna. Má tá an réimse ag teastáil, cuireann sé seo iallach ar an úsáideoir rogha a dhéanamh. Ní chuirfear an rogha bán san áireamh má tá blank=false ``sa réimse samhail agus luach sainráite ``default (roghnófar an luach default i dtosach ina ionad).

Faoi dheireadh, tabhair faoi deara gur féidir leat an réimse foirme a úsáidtear do réimse samhail ar leith a shárú. Féach `Sárú ar na réimsí réamhshocraithe `_ thíos.

Sampla iomlánLink to this heading

Smaoinigh ar an tacar samhlacha seo:

Code
from django.db import models
from django.forms import ModelForm

TITLE_CHOICES = {
    "MR": "Mr.",
    "MRS": "Mrs.",
    "MS": "Ms.",
}


class Author(models.Model):
    name = models.CharField(max_length=100)
    title = models.CharField(max_length=3, choices=TITLE_CHOICES)
    birth_date = models.DateField(blank=True, null=True)

    def __str__(self):
        return self.name


class Book(models.Model):
    name = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)


class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ["name", "title", "birth_date"]


class BookForm(ModelForm):
    class Meta:
        model = Book
        fields = ["name", "authors"]

Leis na samhlacha seo, bheadh na fo-aicmí `ModelForm ``thuas comhionann go garbh leis seo (is é an t-aon difríocht ná an modh `save () `, a phléifimid i nóiméad. ):

Code
from django import forms


class AuthorForm(forms.Form):
    name = forms.CharField(max_length=100)
    title = forms.CharField(
        max_length=3,
        widget=forms.Select(choices=TITLE_CHOICES),
    )
    birth_date = forms.DateField(required=False)


class BookForm(forms.Form):
    name = forms.CharField(max_length=100)
    authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())

Bailíochtú ar SamhlfhoirmeLink to this heading

Tá dhá phríomhchéim i gceist le “Modelform” a bhailíochtú:

  1. Validating the form

  2. <validating-objects>:ref: `An samhail samhail a bhailíochtú `

Just like normal form validation, model form validation is triggered implicitly when calling is_valid() or accessing the errors attribute and explicitly when calling full_clean(), although you will typically not use the latter method in practice.

Model validation is triggered from within the form validation step right after the form's clean() method is called. First, the model's full_clean() is called with validate_unique=False and validate_constraints=False, then the model's validate_unique() and validate_constraints() methods are called in order.

Sárú ar an modh ``clean () ``Link to this heading

Is féidir leat an modh ``clean () ``a shárú ar fhoirm mhúnla chun bailíochtú breise a sholáthar ar an mbealach céanna is féidir leat ar ghnáthfhoirm.

Beidh tréith instance i gcás foirme samhail atá ceangailte le réad samhail a thugann rochtain dá mhodhanna ar an samhail shonrach sin.

Idirghníomhaíocht le bailíochtúLink to this heading

Mar chuid den phróiseas bailíochtaithe, glaóidh ModelForm ``modh `glan () gach réimse ar do mhúnla a bhfuil réimse comhfhreagrach aige ar d'fhoirm. Má tá aon réimsí samhlacha eisiata agat, ní reáchtálfar bailíochtú ar na réimsí sin. Féach an doiciméadach:doc: `bailíochtú foirme' le haghaidh tuilleadh eolais fa</ref/forms/validation> oin gcaoi a n-oibríonn glanadh agus bailíochtú

The model's clean() method will be called before any uniqueness or constraint checks are made. See Validating objects for more information on the model's clean() hook.

Breithnithe maidir le error_messages an tsamhailLink to this heading

<django.db.models.Field.error_messages>Bíonn teachtaireachtaí earráide a shainmhínítear ag leibhéal:attr: réimse foirme <django.forms.Field.error_messages>`nó ag leibhéal:ref: `form Meta<modelforms-overriding-default-fields> tosaíocht i gcónaí thar na teachtaireachtaí earráide a shainmhínítear ag leibhéal:attr: `réimse samhail `.

<validating-objects>Ní úsáidtear teachtaireachtaí earráide a shainmhínítear ar:attr: réimsí samhail <django.db.models.Field.error_messages>`ach nuair a ardaítear an ``ValidationError` le linn na céime:ref: bailíochtú samhail agus nach sainmhínítear aon teachtaireachtaí earráide comhfhreagracha ag leibhéal na foirme.

Is féidir leat na teachtaireachtaí earráide ó NON_FIELD_ERRORS` arna ardú trí bhailíochtú samhail a chur trí:data: ~django.core.exceptions.non_field_errors eochair leis an bhfoclóir error_messages` de rang Meta` istigh ModelForm:

Code
from django.core.exceptions import NON_FIELD_ERRORS
from django.forms import ModelForm


class ArticleForm(ModelForm):
    class Meta:
        error_messages = {
            NON_FIELD_ERRORS: {
                "unique_together": "%(model_name)s's %(field_labels)s are not unique.",
            }
        }

An modh ``save () ``Link to this heading

Tá modh save () ``ag gach `ModelForm freisin. Cruthaíonn agus sábhálann an modh seo réad bunachar sonraí ó na sonraí atá ceangailte leis an bhfoirm. Is féidir le fo-aicme de ModelForm` glacadh le samhail atá ann cheana mar an argóint eochairfhocal instance; má sholáthraítear é seo, déanfaidh ``save () ``an cás sin a nuashonrú. Mura soláthraítear é, cruthóidh ``save () ``sampla nua den tsamhail shonraithe:

Python console
>>> from myapp.models import Article
>>> from myapp.forms import ArticleForm

# Create a form instance from POST data.
>>> f = ArticleForm(request.POST)

# Save a new Article object from the form's data.
>>> new_article = f.save()

# Create a form to edit an existing Article, but use
# POST data to populate the form.
>>> a = Article.objects.get(pk=1)
>>> f = ArticleForm(request.POST, instance=a)
>>> f.save()

Tabhair faoi deara mura bhfuil an fhoirm:ref: bailíochtaithe `, déanfar glaoch ar <validation-on-modelform>save () amhlaidh trí ``form.errors a sheiceáil. Ardófar Error lua mura ndéanann na sonraí san fhoirm bailíochtú - ie, má mheasóidh form.errors go True`.

Mura bhfuil réimse roghnach le feiceáil i sonraí na foirme, úsáideann an samhail mar thoradh air an réimse samhail: attr: ~django.db.models.field.default, má tá ceann ann, don réimse sin. <select multiple>Ní bhaineann an t-iompar seo le réimsí a úsáide:class: ~django.forms.checkboxInput, :class: ~django.forms.checkboxSelectMultiple, no:class: ~django.forms.selectMultiple (nó aon ghuirléid saincheaptha ciú:meth: ~django.forms.widget.value_omitted_fromdat_dat_dat_Filleann modh ``False` i gcónaí) ós rud é nach bhfuil bosca seiceála neamhsheiceáilte agus ```` neamhroghnaithe le feiceáil i sonraí aighneachta foirme HTML. Úsáid réimse nó giuirléid fhoirme saincheaptha má tá API á dhearadh agat agus má theastaíonn uait an t-iompar titim réamhshocraithe do réimse a úsáideann ceann de na giuirléidí seo.

Glacann an modh save () ``seo le hargóint eochairfhocal roghnach ``commit, a ghlacann le TrueFalse. Má ghlaonn tú ar save () ``le `Commit=false, ansin cuirfidh sé rud ar ais nár shábháiltear go fóill chuig an mbunachar sonraí. Sa chás seo, is fútsa atá sé glaoch ar save () ``ar an gcás samhail mar thoradh air. <ref-models-force-insert>Tá seo úsáideach más mian leat próiseáil saincheaptha a dhéanamh ar an réad sula ndéanann é a shábháil, más mian leat ceann de na roghanna speisialaithe: ref: `samhail sábhála `a úsáid. Is é ``commit True de réir réamhshocraithe.

Feictear fo-éifeacht eile a bhaineann le `Commit=false ``a úsáid nuair a bhíonn gaol go leor ag do mhúnla le samhail eile. Má tá gaol go leor ag do mhúnla agus má shonraíonn tú ``Commit=false ``nuair a shábhálann tú foirm, ní féidir le Django sonraí na foirme a shábháil láithreach don ghaol go leor. Tá sé seo toisc nach féidir sonraí go leor a shábháil mar shampla go dtí go mbeidh an cás sa bhunachar sonraí.

Chun oibriú timpeall ar an bhfadhb seo, gach uair a shábhálann tú foirm ag baint úsáide as Commit=false`, cuireann Django modh save_m2m () ``le do fho-aicme ``ModelForm. Tar éis duit an cás a tháirgeann an fhoirm a shábháil de láimh, is féidir leat `save_m2m () ``a ghairm chun na sonraí foirme go leor a shábháil. Mar shampla:

Python console
# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)

# Create, but don't save the new author instance.
>>> new_author = f.save(commit=False)

# Modify the author in some way.
>>> new_author.some_field = "some_value"

# Save the new instance.
>>> new_author.save()

# Now, save the many-to-many data for the form.
>>> f.save_m2m()

Calling save_m2m() is only required if you use save(commit=False). When you use a save() on a form, all data -- including many-to-many data -- is saved without the need for any additional method calls. For example:

Python console
# Create a form instance with POST data.
>>> a = Author()
>>> f = AuthorForm(request.POST, instance=a)

# Create and save the new author instance. There's no need to do anything else.
>>> new_author = f.save()

Seachas na modhanna save () ``agus `save_m2m ()`, oibríonn Modelform díreach ar an mbealach céanna le haon fhoirm foirme eile. Mar shampla, úsáidtear an modh is_valid () ``chun bailíocht a sheiceáil, úsáidtear an modh ``is_multipart () chun a chinneadh an gá uaslódáil comhad ilpháirteach ó fhoirm (agus dá bhrí sin an gcaithfear request.files a chur chuig an bhfoirm), srl. Féach: binding-uploaded-files le haghaidh tuilleadh faisnéise.

Roghnú na réimsí le húsáidLink to this heading

Moltar go láidir duit gach réimse a shocrú go sainráite ar chóir a chur in eagar sa fhoirm ag baint úsáide as an tréith fields. D'fhéadfadh fadhbanna slándála a bheith mar thoradh air go héasca nuair a cheadaíonn foirm gan choinne d'úsáideoir réimsí áirithe a shocrú, go háirithe nuair a chuirtear réimsí nua le samhail. Ag brath ar an gcaoi a ndéantar an fhoirm a léiriú, b'fhéidir nach mbeadh an fhadhb le feiceáil fiú ar an leathanach

The alternative approach would be to include all fields automatically, or remove only some. This fundamental approach is known to be much less secure and has led to serious exploits on major websites (e.g. GitHub ).

Tá dhá aicearra ar fáil, áfach, do chásanna inar féidir leat a ráthú nach mbaineann na hábhair imní slándála seo leat:

  1. Socraigh an tréith fields don luach speisialta `__all__' chun a léiriú gur chóir gach réimse sa tsamhail a úsáid. Mar shampla:

    Code
    from django.forms import ModelForm
    
    
    class AuthorForm(ModelForm):
        class Meta:
            model = Author
            fields = "__all__"
    
  2. Socraigh tréith eisiam d'aicme Meta istigh an ModelForm` chuig liosta réimsí atá le eisiamh ón bhfoirm.

    Mar shampla:

    Code
    class PartialAuthorForm(ModelForm):
        class Meta:
            model = Author
            exclude = ["title"]
    

    Ós rud é go bhfuil na 3 réimse ainm, teideal ``agus ``dáta_bhreith` sa tsamhail Údar, beidh na réimsí ainm agus dáta_bhreith` i láthair ar an bhfoirm.

Má úsáidtear ceachtar díobh seo, is é an t-ord a bheidh na réimsí le feiceáil san fhoirm an t-ord a shainmhínítear na réimsí sa tsamhail, agus cásanna ``ManyTomanyField` le feiceáil go deireanach.

Ina theannta sin, cuireann Django an riail seo a leanas i bhfeidhm: má shocraíonn tú Editable=False ar an réimse samhail, ní chuimseoidh an réimse sin aon fhoirme a cruthaíodh ón tsamhail trí ModelForm `.

Sárú ar na réimsí réamhshocraitheLink to this heading

Is réamhshocruithe ciallmhar iad na cineálacha réimse réamhshocraithe, mar a thuairiscítear sa tábla Cineálacha réimse `_ thuas. Má tá ``Datefield` agat i do mhúnla, is dócha gur mhaith leat é sin a léiriú mar Datefield i do fhoirm. Ach tugann ``ModelForm ``an solúbthacht duit an réimse foirme a athrú do mhúnla ar leith.

Chun giuirléid saincheaptha do réimse a shonrú, bain úsáid as an tréith giuirléidí ``den aicme ``Meta istigh. Ba chóir go mbeadh sé seo ina fhoclóir a mhapáil ainmneacha réimse chuig ranganna nó cásanna

<textarea><input type="text">Mar shampla, más mian leat an Charfield don tréith ainm ``de ``Údar a léiriú le`` ```` ```` ```` in ionad a réamhshocraithe ```` `, is féidir leat giuirléid an réimse a shárú:

Code
from django.forms import ModelForm, Textarea
from myapp.models import Author


class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ["name", "title", "birth_date"]
        widgets = {
            "name": Textarea(attrs={"cols": 80, "rows": 20}),
        }

Glacann an foclóir giuirléidí ``le ceachtar cásanna giuirléid (m.sh., ``Textarea (...)) nó ranganna (m.sh., Textarea). Tabhair faoi deara go ndéantar neamhaird ar an bhfoclóir ``giuirlisí ``do réimse samhail le tréith ``roghnaí` neamh-folamh. Sa chás seo, ní mór duit an réimse foirme a shárú chun giuirléid dhifriúil a úsáid.

Ar an gcaoi chéanna, is féidir leat tréithe labels, help_texts` agus error_messages sa rang Meta` istigh a shonrú más mian leat réimse a shaincheapadh tuilleadh.

Mar shampla más mian leat foclaíocht na teaghráin uile atá os comhair an úsáideora a shaincheapadh don réimse ``ainm ``:

Code
from django.utils.translation import gettext_lazy as _


class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ["name", "title", "birth_date"]
        labels = {
            "name": _("Writer"),
        }
        help_texts = {
            "name": _("Some useful help text."),
        }
        error_messages = {
            "name": {
                "max_length": _("This writer's name is too long."),
            },
        }

Is féidir leat field_classesformfield_callback a shonrú freisin chun an cineál réimsí a shaincheapadh ag an bhfoirm.

Mar shampla, dá dteastaíonn uait MyslugFormField` a úsáid don réimse slug, d'fhéadfá an méid seo a leanas a dhéanamh:

Code
from django.forms import ModelForm
from myapp.models import Article


class ArticleForm(ModelForm):
    class Meta:
        model = Article
        fields = ["pub_date", "headline", "content", "reporter", "slug"]
        field_classes = {
            "slug": MySlugFormField,
        }

nó:

Code
from django.forms import ModelForm
from myapp.models import Article


def formfield_for_dbfield(db_field, **kwargs):
    if db_field.name == "slug":
        return MySlugFormField()
    return db_field.formfield(**kwargs)


class ArticleForm(ModelForm):
    class Meta:
        model = Article
        fields = ["pub_date", "headline", "content", "reporter", "slug"]
        formfield_callback = formfield_for_dbfield

Faoi dheireadh, más mian leat smacht iomlán ar réimse - lena n-áirítear a chineál, bailíochtóirí, riachtanacha, srl. - is féidir leat é seo a dhéanamh trí réimsí a shonrú go dearbhaithe mar a dhéanfá i ``Foirm 'rialta.

Más mian leat bailíochtóirí réimse a shonrú, is féidir leat é sin a dhéanamh tríd an réimse a shainiú go dearbhaithe agus a pharaiméadar ``bailíodóirí ``a shocrú:

Code
from django.forms import CharField, ModelForm
from myapp.models import Article


class ArticleForm(ModelForm):
    slug = CharField(validators=[validate_slug])

    class Meta:
        model = Article
        fields = ["pub_date", "headline", "content", "reporter", "slug"]

Logánú réimsí a chumasúLink to this heading

De réir réamhshocraithe, ní dhéanfaidh na réimsí i ModelForm ``a gcuid sonraí a logánú. Chun logánú do réimsí a chumasú, is féidir leat an tréith ``localized_fields` a úsáid ar an rang Meta.

Code
>>> from django.forms import ModelForm
>>> from myapp.models import Author
>>> class AuthorForm(ModelForm):
...     class Meta:
...         model = Author
...         localized_fields = ['birth_date']

Má shocraítear localized_fields go dtí an luach speisialta '__all__', beidh gach réimse logánaithe.

Foirm oidhreachtLink to this heading

As with basic forms, you can extend and reuse ModelForm classes by inheriting them. This is useful if you need to declare extra fields or extra methods on a parent class for use in a number of forms derived from models. For example, using the previous ArticleForm class:

Python console
>>> class EnhancedArticleForm(ArticleForm):
...     def clean_pub_date(self): ...
...

Cruthaíonn sé seo foirm a iompraíonn go cosúil le ArticleForm, ach amháin go bhfuil roinnt bailíochtaithe agus glantacháin bhreise ann don réimse pub_date.

Féadfaidh tú rang istigh Meta an tuismitheora a fho-aicmiú freisin más mian leat na liostaí Meta.Fields nó Meta.Exclude` a athrú:

Python console
>>> class RestrictedArticleForm(EnhancedArticleForm):
...     class Meta(ArticleForm.Meta):
...         exclude = ["body"]
...

Cuireann sé seo an modh breise leis an EnhancedArticleForm agus athraíonn sé an ArticleForm.meta` bunaidh chun réimse amháin a bhaint.

Tá cúpla rud le tabhairt faoi deara, áfach.

  • Tá feidhm ag gnáthrialacha um réiteach ainm Python. Má tá bunaicmí iolracha agat a dhearbhíonn rang istigh Meta`, úsáidfear ach an chéad cheann. Ciallaíonn seo ``Meta an linbh, má tá sé ann, ar shlí eile Meta an chéad thuismitheora, srl.

  • Is féidir oidhreacht a dhéanamh ó Form ``agus `ModelForm araon ag an am céanna, áfach, ní mór duit a chinntiú go bhfuil ``ModelForm ``le feiceáil ar dtús sa MRO. Tá sé seo toisc go mbraitheann na ranganna seo ar mhithaiclasanna éagsúla agus ní féidir ach meiteachlas amháin a bheith ag rang.

  • Is féidir Field a bhaint go dearbhaithe ó rang tuismitheoirí tríd an ainm a shocrú mar ``None ``ar an bhfo-aicme.

    Ní féidir leat an teicníc seo a úsáid ach chun diúltú as réimse a shainmhíníonn go dearbhaithe ag rang tuismitheoirí; ní chuirfidh sé cosc ar an meiteachlas ModelForm réimse réimse réamhshocraithe a ghiniúint. Chun diúltú ó réimsí réamhshocraithe, féach:ref: modelforms-selecting-fields.

Luachanna tosaigh ar fáilLink to this heading

Mar is amhlaidh le foirmeacha rialta, is féidir sonraí tosaigh do fhoirmeacha a shonrú trí pharaiméadar tosaithe a shonrú agus an fhoirm á chur i bhfeidhm. Déanfaidh luachanna tosaigh a chuirtear ar fáil ar an mbealach seo athsháraíonn luachanna tosaigh ón réimse foirme agus luachanna ó shampla samhail Mar shampla:

Python console
>>> article = Article.objects.get(pk=1)
>>> article.headline
'My headline'
>>> form = ArticleForm(initial={"headline": "Initial headline"}, instance=article)
>>> form["headline"].value()
'Initial headline'

Feidhm monarcha ModelFormLink to this heading

Is féidir leat foirmeacha a chruthú ó mhúnla ar leith ag baint úsáide as an bhfeidhm neamhspleách: func: ~django.forms.models.modelform_factory, in ionad sainmhíniú ranga a úsáid. D'fhéadfadh sé seo a bheith níos áisiúla mura bhfuil go leor saincheaptha agat le déanamh:

Python console
>>> from django.forms import modelform_factory
>>> from myapp.models import Book
>>> BookForm = modelform_factory(Book, fields=["author", "title"])

Is féidir é seo a úsáid freisin chun modhnuithe a dhéanamh ar fhoirmeacha atá ann cheana, mar shampla trí na giuirléidí atá le húsáid le haghaidh réimse ar leith a shonrú:

Python console
>>> from django.forms import Textarea
>>> Form = modelform_factory(Book, form=BookForm, widgets={"title": Textarea()})

Is féidir na réimsí atá le cur san áireamh a shonrú ag baint úsáide as na hargóintí eochairfhocal réimsí ``agus ``eisiam, nó na tréithe comhfhreagracha ar an aicme Meta istigh Modelform. Féach an doiciméadú ModelForm:ref: modelforms-selecting-fields le do thoil.

... nó logánú a chumasú do réimsí ar leith:

Python console
>>> Form = modelform_factory(Author, form=AuthorForm, localized_fields=["birth_date"])

Foirmeacha múnlaLink to this heading

class models.BaseModelFormSetLink to this definition

Cosúil le: doc: foirmeacha rialta, soláthraíonn D</topics/forms/formsets> jango cúpla rang foirm fheabhsaithe chun oibriú le samhlacha Django a dhéanamh níos áisiúla. Déanaimis an tsamhail ``Údar` a athúsáid as thuas:

Python console
>>> from django.forms import modelformset_factory
>>> from myapp.models import Author
>>> AuthorFormSet = modelformset_factory(Author, fields=["name", "title"])

Ag baint úsáide as `réimsí ``cuirtear srian ar an bhfoirmshraith chun na réimsí a thugtar a úsáid amháin. De rogha air sin, is féidir leat cur chuige “diúltú amach” a ghlacadh, ag sonrú cé na réimsí atá le eisiamh:

Python console
>>> AuthorFormSet = modelformset_factory(Author, exclude=["birth_date"])

Cruthóidh sé seo tacar foirme atá in ann oibriú leis na sonraí a bhaineann leis an tsamhail ``Údar`. Oibríonn sé díreach cosúil le foirmshraith rialta:

Python console
>>> formset = AuthorFormSet()
>>> print(formset)
<input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS"><input type="hidden" name="form-INITIAL_FORMS" value="0" id="id_form-INITIAL_FORMS"><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS"><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS">
<div><label for="id_form-0-name">Name:</label><input id="id_form-0-name" type="text" name="form-0-name" maxlength="100"></div>
<div><label for="id_form-0-title">Title:</label><select name="form-0-title" id="id_form-0-title">
<option value="" selected>---------</option>
<option value="MR">Mr.</option>
<option value="MRS">Mrs.</option>
<option value="MS">Ms.</option>
</select><input type="hidden" name="form-0-id" id="id_form-0-id"></div>

An tacar ceisteanna a athrúLink to this heading

De réir réamhshocraithe, nuair a chruthaíonn tú tacar foirme ó mhúnla, úsáidfidh an tacar foirme tacar ceisteanna a chuimsíonn gach rud sa tsamhail (m.sh., Author.Objects.all () `). Is féidir leat an t-iompar seo a shárú tríd an argóint queryset a úsáid:

Python console
>>> formset = AuthorFormSet(queryset=Author.objects.filter(name__startswith="O"))

De rogha air sin, is féidir leat fo-aicme a chruthú a leagann self.queryset i __init__:

Code
from django.forms import BaseModelFormSet
from myapp.models import Author


class BaseAuthorFormSet(BaseModelFormSet):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.queryset = Author.objects.filter(name__startswith="O")

Ansin, cuir do rang ``BaseAuthorFormSet ``chuig feidhm an mhonarcha:

Python console
>>> AuthorFormSet = modelformset_factory(
...     Author, fields=["name", "title"], formset=BaseAuthorFormSet
... )

Más mian leat tacar foirme a thabhairt ar ais nach n-áirítear * aon chás den tsamhail atá ann cheana féin, is féidir leat QuerySet folamh a shonrú:

Python console
>>> AuthorFormSet(queryset=Author.objects.none())

An fhoirm a athrúLink to this heading

De réir réamhshocraithe, nuair a úsáideann tú modelformset_factory, cruthófar foirm mhúnla ag baint úsáidea:func: ~django.forms.models.modelform_factory. Go minic, is féidir go mbeadh sé úsáideach foirm mhúnla saincheaptha a shonrú. Mar shampla, is féidir leat foirm mhúnla saincheaptha a chruthú a bhfuil bailíochtú saincheaptha aige:

Code
class AuthorForm(forms.ModelForm):
    class Meta:
        model = Author
        fields = ["name", "title"]

    def clean_name(self):
        # custom validation for the name field
        ...

Ansin, cuir d'fhoirm mhúnla chuig feidhm an mhonarcha:

Code
AuthorFormSet = modelformset_factory(Author, form=AuthorForm)

Ní gá i gcónaí foirm mhúnla saincheaptha a shainiú. Tá roinnt argóintí ag an bhfeidhm modelformset_factory` a chuirtear tríd chuig modelform_factory`, a bhfuil cur síos orthu thíos.

Giuirléidí a shonrú le húsáid sa fhoirm le giuirléidíLink to this heading

Ag baint úsáide as an paraiméadar giuirlisí ``, is féidir leat foclóir luachanna a shonrú chun rang giuirléid ``ModelForm a shaincheapadh do réimse áirithe. Oibríonn sé seo ar an mbealach céanna agus a oibríonn an foclóir giuirléid' ar an aicme ``Meta istigh de ModelForm `:

Python console
>>> AuthorFormSet = modelformset_factory(
...     Author,
...     fields=["name", "title"],
...     widgets={"name": Textarea(attrs={"cols": 80, "rows": 20})},
... )

Logánú a chumasú do réimsí le localized_fieldsLink to this heading

Ag baint úsáide as an paraiméadar localized_fields, is féidir leat logánú a chumasú do réimsí san fhoirm.

Code
>>> AuthorFormSet = modelformset_factory(
...     Author, fields=['name', 'title', 'birth_date'],
...     localized_fields=['birth_date'])

Má shocraítear localized_fields go dtí an luach speisialta '__all__', beidh gach réimse logánaithe.

Luachanna tosaigh ar fáilLink to this heading

Mar is amhlaidh le foirmeacha rialta, is féidir: ref: sonraí tosaigh a shonrú <formsets-initial-data>do fhoirmeacha sa tacar foirmeacha trí pharaiméadar ``initial` a shonrú agus an aicme foirmeacha samhail a chuirtear ar ais ag: func: ~django.forms.models.modelformset_factory. Mar sin féin, le foirmeacha samhlacha, ní bhaineann na luachanna tosaigh ach le foirmeacha breise, iad siúd nach bhfuil ceangailte le samhail shampla atá ann cheana. Má sháraíonn fad tosaithe líon na bhfoirmeacha breise, déantar neamhaird ar na sonraí tosaigh iomarcacha. Mura n-athraíonn an t-úsáideoir na foirmeacha breise le sonraí tosaigh, ní dhéanfar iad a bhailíochtú ná a shábháil.

Rudaí a shábháil sa fhoirmshraithLink to this heading

Mar is amhlaidh le ModelForm`, is féidir leat na sonraí a shábháil mar réad samhail. Déantar é seo le modh ``save () ``an tsraith foirmeacha:

Python console
# Create a formset instance with POST data.
>>> formset = AuthorFormSet(request.POST)

# Assuming all is valid, save the data.
>>> instances = formset.save()

Tugann an modh `save () ``ar ais na cásanna a shábháiltear chuig an mbunachar sonraí. Mura n-athraigh sonraí cás ar leith sna sonraí ceangailte, ní shábháilfear an cás sa bhunachar sonraí agus ní chuirfear san áireamh sa luach tuairisceáin (``instancs', sa sampla thuas).

When fields are missing from the form (for example because they have been excluded), these fields will not be set by the save() method. You can find more information about this restriction, which also holds for regular model forms, in Selecting the fields to use.

Pas Commit=False` chun na cásanna samhail neamhshábháilte a thabhairt ar ais:

Python console
# don't save to the database
>>> instances = formset.save(commit=False)
>>> for instance in instances:
...     # do something with instance
...     instance.save()
...

Tugann sé seo an cumas duit sonraí a cheangal leis na cásanna sula ndéantar iad a shábháil leis an mbunachar sonraí. Má tá ManyTomanyField sa tacar foirme, beidh ort glaoch ar `formset.save_m2m () ``chun a chinntiú go sábhálfar na caidrimh go leor i gceart.

Tar éis glaoch ar ``save () ``,, beidh trí thréith nua ag do shraith foirmeacha samhail ina bhfuil athruithe an fhoirmshraith:

models.BaseModelFormSet.changed_objectsLink to this definition
models.BaseModelFormSet.deleted_objectsLink to this definition
models.BaseModelFormSet.new_objectsLink to this definition

Líon na rudaí in-eagarthóireachta a theorannúLink to this heading

Mar is amhlaidh le foirmeacha rialta, is féidir leat na paraiméadair max_num agus extra a úsáid to:func: ~django.forms.models.modelformset_factory chun líon na bhfoirmeacha breise a thaispeántar a theorannú.

Ní chuireann max_num cosc ar rudaí atá ann cheana a thaispeáint:

Python console
>>> Author.objects.order_by("name")
<QuerySet [<Author: Charles Baudelaire>, <Author: Paul Verlaine>, <Author: Walt Whitman>]>

>>> AuthorFormSet = modelformset_factory(Author, fields=["name"], max_num=1)
>>> formset = AuthorFormSet(queryset=Author.objects.order_by("name"))
>>> [x.name for x in formset.get_queryset()]
['Charles Baudelaire', 'Paul Verlaine', 'Walt Whitman']

<understanding-the-managementform>Chomh maith leis sin, ní choisceann extra=0 cásanna samhail nua a chruthú mar is féidir leat: ref: foirmeacha breise a chur le JavaScript `nó seol sonraí POST breise. Féach: ref: `model-formsets-edit-only maidir le conas é seo a dhéanamh.

Má tá luach max_num níos mó ná líon na rudaí gaolmhara atá ann cheana, cuirfear foirmeacha bán breise suas le extra leis an tacar foirmeacha, fad nach mbeidh líon iomlán na bhfoirmeacha níos mó ná max_num:

Python console
>>> AuthorFormSet = modelformset_factory(Author, fields=["name"], max_num=4, extra=2)
>>> formset = AuthorFormSet(queryset=Author.objects.order_by("name"))
>>> for form in formset:
...     print(form)
...
<div><label for="id_form-0-name">Name:</label><input id="id_form-0-name" type="text" name="form-0-name" value="Charles Baudelaire" maxlength="100"><input type="hidden" name="form-0-id" value="1" id="id_form-0-id"></div>
<div><label for="id_form-1-name">Name:</label><input id="id_form-1-name" type="text" name="form-1-name" value="Paul Verlaine" maxlength="100"><input type="hidden" name="form-1-id" value="3" id="id_form-1-id"></div>
<div><label for="id_form-2-name">Name:</label><input id="id_form-2-name" type="text" name="form-2-name" value="Walt Whitman" maxlength="100"><input type="hidden" name="form-2-id" value="2" id="id_form-2-id"></div>
<div><label for="id_form-3-name">Name:</label><input id="id_form-3-name" type="text" name="form-3-name" maxlength="100"><input type="hidden" name="form-3-id" id="id_form-3-id"></div>

Cuireann luach max_num de None (an réamhshocrú) teorainn ard ar líon na bhfoirmeacha a thaispeántar (1000). Go praiticiúil tá sé seo coibhéiseach le haon teorainn.

Cruthú rudaí nua a choscLink to this heading

Ag baint úsáide as an paraiméadar edit_only, is féidir leat cosc a chur ar chruthú aon rudaí nua:

Python console
>>> AuthorFormSet = modelformset_factory(
...     Author,
...     fields=["name", "title"],
...     edit_only=True,
... )

Anseo, ní dhéanfaidh an tacar foirme ach cásanna ``Údar` atá ann cheana a chur in eagar. Ní chruthófar nó a chur in eagar aon rudaí eile.

Ag baint úsáide as foirmshraith samhail i radharcLink to this heading

Tá foirmeacha samhlacha an-chosúil le foirmeacha. Ligean le rá gur mhaith linn tacar foirme a chur i láthair chun cásanna samhail ``Údar` a chur in eagar:

Code
from django.forms import modelformset_factory
from django.shortcuts import render
from myapp.models import Author


def manage_authors(request):
    AuthorFormSet = modelformset_factory(Author, fields=["name", "title"])
    if request.method == "POST":
        formset = AuthorFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            # do something.
    else:
        formset = AuthorFormSet()
    return render(request, "manage_authors.html", {"formset": formset})

Mar a fheiceann tú, níl loighic radharc tacar foirmeacha samhail difriúil go mór ná loighic thacar foirmeacha “gnáth”. Is é an t-aon difríocht ná go nglaoimid ar ``formset.save () ``chun na sonraí a shábháil sa bhunachar sonraí. (Rinneadh cur síos air seo thuas, in:ref: saving-objects-in-the-formset.)

Sárú ar clean () ``ar `ModelFormSetLink to this heading

Just like with a ModelForm, by default the clean() method of a ModelFormSet will validate that none of the items in the formset violate the unique constraints on your model (either unique, unique_together or unique_for_date|month|year). If you want to override the clean() method on a ModelFormSet and maintain this validation, you must call the parent class's clean method:

Code
from django.forms import BaseModelFormSet


class MyModelFormSet(BaseModelFormSet):
    def clean(self):
        super().clean()
        # example custom validation across forms in the formset
        for form in self.forms:
            # your custom formset validation
            ...

Tabhair faoi deara freisin faoin am a shroicheann tú an chéim seo, go bhfuil cásanna samhail aonair cruthaithe cheana féin do gach Foirm ``. leor luach a mhodhnú i `form.cleaned_data ``chun dul i bhfeidhm ar an luach sábháltha. Más mian leat luach a mhodhnú in `ModelFormSet.clean () ``ní mór duit ``form.instance a mhodhnú:

Code
from django.forms import BaseModelFormSet


class MyModelFormSet(BaseModelFormSet):
    def clean(self):
        super().clean()

        for form in self.forms:
            name = form.cleaned_data["name"].upper()
            form.cleaned_data["name"] = name
            # update the instance value.
            form.instance.name = name

Ag baint úsáide as tacar ceisteanna saincheapthaLink to this heading

Mar a dúradh níos luaithe, is féidir leat an tacar ceisteanna réamhshocraithe a úsáideann an tacar foirmeacha samhail a shárú:

Code
from django.forms import modelformset_factory
from django.shortcuts import render
from myapp.models import Author


def manage_authors(request):
    AuthorFormSet = modelformset_factory(Author, fields=["name", "title"])
    queryset = Author.objects.filter(name__startswith="O")
    if request.method == "POST":
        formset = AuthorFormSet(
            request.POST,
            request.FILES,
            queryset=queryset,
        )
        if formset.is_valid():
            formset.save()
            # Do something.
    else:
        formset = AuthorFormSet(queryset=queryset)
    return render(request, "manage_authors.html", {"formset": formset})

Tabhair faoi deara go rachaimid an argóint queryset sna cásanna POST ``agus `GET sa sampla seo.

Ag baint úsáide as an bhfoirm sa teimpléadLink to this heading

Tá trí bhealach ann chun tacar foirme a rinneadh i dteimpléad Django.

Ar dtús, is féidir leat ligean don fhoirmset an chuid is mó den obair a dhéanamh:

Django template
<form method="post">
    {{ formset }}
</form>

Ar an dara dul síos, is féidir leat an tacar foirme a rinneadh de láimh, ach lig don fhoirm déileáil leis féin:

Django template
<form method="post">
    {{ formset.management_form }}
    {% for form in formset %}
        {{ form }}
    {% endfor %}
</form>

Nuair a dhéanann tú na foirmeacha a rinneadh de láimh tú féin, bí cinnte an fhoirm bhainistíochta a thabhairt mar a thaispeán <understanding-the-managementform>Féach an:ref: `doiciméadú foirm bhainistíochta `.

Sa tríú háit, is féidir leat gach réimse a rinneadh de láimh

Django template
<form method="post">
    {{ formset.management_form }}
    {% for form in formset %}
        {% for field in form %}
            {{ field.label_tag }} {{ field }}
        {% endfor %}
    {% endfor %}
</form>

Má roghnaíonn tú an tríú modh seo a úsáid agus mura ndéanann tú athrá thar na réimsí le lúb {% for%}, beidh ort an príomhréimse eochair a rinneadh. Mar shampla, má bhí réimsí ainm ``agus ``aois á ndéanamh agat de mhúnla:

Django template
<form method="post">
    {{ formset.management_form }}
    {% for form in formset %}
        {{ form.id }}
        <ul>
            <li>{{ form.name }}</li>
            <li>{{ form.age }}</li>
        </ul>
    {% endfor %}
</form>

Tabhair faoi deara conas is gá dúinn {{form.id}} a rinneadh go sainráite. Cinntíonn sé seo go n-oibreoidh an tacar foirme samhail, sa chás POST `, i gceart. (Glacann an sampla seo le príomh-eochair darb ainm id`. Má tá d'eochair phríomhúil féin sainmhínithe go sainráite agat nach dtugtar id, déan cinnte go ndéantar é a léiriú.)

Foirmeacha inlíneLink to this heading

class models.BaseInlineFormSetLink to this definition

Is ciseal beag tearbhaithe é foirmeacha inlíne ar bharr foirmeacha samhlacha. Déanann siad seo an cás oibriú le rudaí gaolmhara trí eochair eachtrach a shimpliú. Cuir i gcás go bhfuil an dá mhúnla seo agat:

Code
from django.db import models


class Author(models.Model):
    name = models.CharField(max_length=100)


class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)

Más mian leat tacar foirme a chruthú a ligeann duit leabhair a bhaineann le húdar áirithe a chur in eagar, d'fhéadfá seo a dhéanamh:

Python console
>>> from django.forms import inlineformset_factory
>>> BookFormSet = inlineformset_factory(Author, Book, fields=["title"])
>>> author = Author.objects.get(name="Mike Royko")
>>> formset = BookFormSet(instance=author)

<formset-prefix><model name>``BookformSet```'s:ref: réimír `is é ```book_set'` (_set). Má tá a: attr: ~Django.db.Models.ForeignKey.Related_Name de Book go Author `,`` Book``, úsáidtear é sin ina ionad.

Modhanna forchoitianta ar inlineFormSetLink to this heading

Agus modhanna a shárú ar InlineFormSet`, ba cheart duit fo-aicme: ~Models.BaseLineFormSet seachas: ~Models.BaseModelFormSet seachas: ~Models.BaseModelFormSet.

Mar shampla, más mian leat ``clean () ``a shárú:

Code
from django.forms import BaseInlineFormSet


class CustomInlineFormSet(BaseInlineFormSet):
    def clean(self):
        super().clean()
        # example custom validation across forms in the formset
        for form in self.forms:
            # your custom formset validation
            ...

Féach freis:ref: model-formsets-overriding-clean.

Ansin nuair a chruthaíonn tú do shraith foirme inlíne, pas isteach san argóint roghnach formset:

Python console
>>> from django.forms import inlineformset_factory
>>> BookFormSet = inlineformset_factory(
...     Author, Book, fields=["title"], formset=CustomInlineFormSet
... )
>>> author = Author.objects.get(name="Mike Royko")
>>> formset = BookFormSet(instance=author)

Níos mó ná eochair eachtrach amháin don tsamhail chéannaLink to this heading

Má tá níos mó ná eochair eachtrach amháin don tsamhail chéanna i do mhúnla, beidh ort an débhríocht a réiteach de láimh ag baint úsáide as fk_name`. Mar shampla, smaoinigh ar an tsamhail seo a leanas:

Code
class Friendship(models.Model):
    from_friend = models.ForeignKey(
        Friend,
        on_delete=models.CASCADE,
        related_name="from_friends",
    )
    to_friend = models.ForeignKey(
        Friend,
        on_delete=models.CASCADE,
        related_name="friends",
    )
    length_in_months = models.IntegerField()

Chun é seo a réiteach, is féidir leat fk_name a úsáid to:func: ~django.forms.models.inlineformset_factory:

Python console
>>> FriendshipFormSet = inlineformset_factory(
...     Friend, Friendship, fk_name="from_friend", fields=["to_friend", "length_in_months"]
... )

Ag baint úsáide as tacar foirmeacha inlíne i radharcLink to this heading

B'fhéidir gur mhaith leat radharc a sholáthar a ligeann d'úsáideoir rudaí gaolmhara samhail a chur in eagar. Seo mar is féidir leat é sin a dhéanamh:

Code
def manage_books(request, author_id):
    author = Author.objects.get(pk=author_id)
    BookInlineFormSet = inlineformset_factory(Author, Book, fields=["title"])
    if request.method == "POST":
        formset = BookInlineFormSet(request.POST, request.FILES, instance=author)
        if formset.is_valid():
            formset.save()
            # Do something. Should generally end with a redirect. For example:
            return HttpResponseRedirect(author.get_absolute_url())
    else:
        formset = BookInlineFormSet(instance=author)
    return render(request, "manage_books.html", {"formset": formset})

Tabhair faoi deara conas a théann muid instance sna cásanna POST ``agus `GET araon.

Giuirléidí a shonrú le húsáid san fhoirm inlíneLink to this heading

Úsáideann `inlineformset_factory modelformset_factory agus cuireann an chuid is mó dá argóintí chuig modelformset_factory`. Ciallaíonn sé seo gur féidir leat an paraiméadar widgets a úsáid ar an mbealach céanna agus é a chur chuig modelformset_factory`. Féach `Giuirléidí a shonrú le húsáid san fhoirm le giuirléidí `_ thuas.