簡體   English   中英

將 django model 的實例加載到模型中

[英]Loading instance of django model into modelform

經過很長一段時間總能在這里找到我的答案,我現在需要真正問我的第一個問題......

我正在處理一個采用模態實例的表單,將其加載到那里(這是它應該做的),之后用戶可以編輯內容並重新保存它。

幾個小時以來,我一直在嘗試將這個初始實例加載到我的表單中。 此表單是源自子 model 的自定義模型表單,可以使用以下 url 找到: path("children_overview/details/<int:child>/edit", ChildEdit, name="Child_Edit"), :

from django import forms
from django.forms import ModelForm
from django.forms.widgets import Select
from django.db.models import Q
from django.utils.translation import gettext_lazy as _

import datetime
import re

from apps.childreg.models import Parents, Child, Child_Reg_Info, Child

class Child(models.Model):
    male = "MAN"
    female = "WOMAN"

    SEXES=[(male, _('male')),(female, _('female'))]

    id = models.AutoField(primary_key=True)
    ExternalId = models.IntegerField(blank=True, null=True)
    ChildId = models.IntegerField(null=True, blank=True)
    FirstName = models.CharField(_('childs first name'), max_length=50, blank=True, null=True)
    LastName = models.CharField(_('childs last name'), max_length=50, blank=True, null=True)
    FullName = models.CharField(_('childs full name'), max_length=100, blank=True, null=True)
    DateOfBirth = models.DateField(_('date of birth'), blank=True, null=True)
    Location = models.ForeignKey(Location, verbose_name=_('location of registration'), on_delete=models.CASCADE)
    Nation = models.ForeignKey(Nation, verbose_name=_('country of registration'), on_delete=models.CASCADE)
    Parents = models.ForeignKey(Parents, verbose_name=_('parents of the child'), on_delete=models.CASCADE)
    Sex = models.CharField(max_length=6, choices=SEXES, verbose_name=_('sex of the child'), null=True, blank=True)
    Born = models.BooleanField(_('Has the child been born?'), default=False)
    Died = models.BooleanField(_("Has the child passed away?"), default=False)

    def stridentifier(self):
        try:
            name = str(self.ExternalId)[13:] + " - " + self.FullName
            return name
        except:
            pass
        name = str(self.ExternalId)[13:] + " - " + str(_("Parents "))
        if self.Parents.FatherFirstName == None:
            return name + self.Parents.MotherFirstName + " " + self.Parents.MotherLastName
        if self.Parents.FatherLastName == None:
            return name + self.Parents.MotherFirstName + " " + self.Parents.MotherLastName
        return name + self.Parents.MotherFirstName + " " + self.Parents.MotherLastName + " & " + self.Parents.FatherFirstName + " " + self.Parents.FatherLastName

    def save(self, *args, **kwargs):
        try:
            self.FullName = self.FirstName + " " + self.LastName
        except:
            self.FullName = None
        super(Child, self).save()

        def __str__(self):
            name = Child.stridentifier(self)
            return name

    @receiver(post_save)
    def post_save(sender, instance, created, *args, **kwargs):
        if created:
            if isinstance(instance, Child):
                instance.ExternalId = CreateID(instance)
                instance.ChildId = ("%06d"%instance.pk)[-6:]
                super(Child, instance).save()
        else:
            pass

    def __str__(self):
        name = Child.stridentifier(self)
        return name

    class Meta:
        verbose_name = _('child')
        verbose_name_plural = _('children')

稍作改動的模型形式:

class ChildForm(ModelForm, forms.Form):

    DateOfBirth = forms.DateField(widget=DateSelectorWidget())

    class Meta:
        model = Child
        exclude = ["ChildId", "ExternalId", "ChildID", "Location", "Nation", "FullName", "Parents", "Died"]


    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields:
            field_name = re.sub(r"(\w)([A-Z])", r"\1 \2", field)
            self.fields[field].widget.attrs.update({'class':'form-control', })#'placeholder': field_name})

整個事情的問題,觀點:

from django.shortcuts import render, redirect, get_object_or_404
from django.utils.translation import gettext_lazy as _
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.forms.models import inlineformset_factory
import datetime

from apps.childreg.forms import NewParentForm, ExParentForm, ParentTypeForm, ChildForm, ChildExtendedForm
from apps.childreg.models import Parents, Child
import algorithms.AccessValidation as AccessValidation

@login_required()
def ChildEdit(request, child):
    ChildInstance = get_object_or_404(Child, pk=child)
    FormEditChild = ChildForm(request.POST, instance=ChildInstance)
    if AccessValidation.Checkin(request, ChildInstance)
        if request.method == 'POST':
           FormEditChild = ChildForm(request.POST, instance=ChildInstance)
    return render(request, "childreg/edit.html", {
    "FormEditChild": FormEditChild,
    "child": ChildInstance,
    })

我省略了整個重新保存過程,因為這並不重要。 首先需要將初始數據加載到在網絡瀏覽器中呈現的表單中。

我已經測試過的東西:

  1. django 是否真的解析了實例?

    是的,我非常專業的內聯打印語句發現代碼已將所需的 ChildInstance 加載到此變量中。

  2. 占位符文本是否有問題(我絕望了):

    不,注釋掉所有內容並沒有真正的區別

  3. request.method == "POST" if 語句下方移動包含表單的 FormEditChild 變量

    沒有...

  4. 從 ChildForm 中省略request.POST語句ChildForm(request.POST, instance=ChildInstance)

    不幸的是,仍然很難

在此先感謝您閱讀本文,非常感謝您為我提供的任何幫助!

好吧,我自己想通了:

感謝: https://projectsplaza.com/add-and-update-data-with-modelform-in-django-3/

當您創建一個包含 model 實例的視圖時,您首先需要使用該實例加載該表單,而不需要在表單 class function 中使用 request.POST 關鍵字。

所以視圖應該是這樣的

@login_required()
def ChildEdit(request, child):
    ChildInstance = get_object_or_404(Child, pk=child)
    if AccessValidation.Checkin(request, ChildInstance):
        FormEditChild = ChildForm(instance=ChildInstance)
        FormEditChildExt = ChildExtendedForm(instance=get_object_or_404(Child_Reg_Info, ChildElaboration=ChildInstance))
        if request.method == 'POST':
            FormEditChild = ChildForm(request.POST, instance=ChildInstance)
            FormEditChildExt = ChildExtendedForm(request.POST, instance=Child_Reg_Info.get_object_or_404(ChildElaboration=ChildInstance))
            if FormEditChild.is_valid():
                FormEditChild.save(commit=False)
#               .....
                FormEditChild.save()
        return render(request, "childreg/edit.html", {
        "FormEditChild": FormEditChild,
        "FormEditChildExt": FormEditChildExt,
        "child": ChildInstance,
        })
    return redirect(AccessValidation.CheckinTLocation)

當您最初加載 forms 時,省略 request.POST 並且僅在應用if request.method == 'POST'語句后以 function 的形式應用它。 通過這種方式,您首先可以使用初始數據呈現表單,而不需要尚不存在的發布數據。 當用戶又名發布數據時: request.method == 'POST'在這種情況下加載並保存表單發布數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM