将Django模型的实例加载到modelform中

2024-06-17 15:35:41 发布

您现在位置:Python中文网/ 问答频道 /正文

在很长一段时间都能在这里找到我的答案之后,我现在需要问我的第一个问题

我正在开发一个表单,它获取一个模态实例,将它加载到那里(这是它应该做的),然后用户可以编辑内容并重新保存它

我已经尝试了几个小时将这个初始实例加载到我的表单中。此表单是源自子模型的自定义模型表单,可使用以下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,
    })

我省略了整个重新保存过程,因为这并不重要。初始数据首先需要加载到webbrowser中呈现的表单中

我已经测试过自己的东西:

  1. django真的解析了这个实例吗

    是的,我疯狂的专业内联打印语句发现代码已将所需的ChildInstance加载到此变量中

  2. 占位符文本有问题吗(我绝望了):

    不,把每件事都说出来并没有什么区别

  3. request.method == "POST"if语句下面移动包含表单的FormEditChild变量

    没有

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

    不幸的是,还是很难拒绝

提前感谢您阅读本文,非常感谢您为我提供的任何帮助

J


Tags: djangoinstancenamefromimportselfchildtrue
1条回答
网友
1楼 · 发布于 2024-06-17 15:35:41

好吧,我自己想出来的:

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

创建包含模型实例的视图时,首先需要将该表单与实例一起加载,而不需要在form类函数中使用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)

最初加载表单时,请省略request.POST,仅在应用了if request.method == 'POST'语句后在表单函数中应用它。通过这种方式,您可以首先使用初始数据呈现表单,而不需要尚未存在的post数据。在这种情况下,当用户发布数据aka:request.method == 'POST'时,将加载并保存表单发布数据

相关问题 更多 >