python Django表单和一些ForeingKey字段

svgewumm  于 2023-01-16  发布在  Python
关注(0)|答案(2)|浏览(137)

请告诉我,当一个模型有很多与其他表相关的字段时,如何制作一个正常的表单来填充这样一个模型?

如何为Project创建窗体?

class City(models.Model):
    obl = models.CharField(max_length=255, choices=REGIONS, default="24", verbose_name="Регион")
    name = models.CharField(max_length=128, verbose_name="Город")
    population = models.IntegerField()

class Address(models.Model):
    city = models.ForeignKey(City, on_delete=models.PROTECT, verbose_name="Город")
    street = models.CharField(max_length=255, verbose_name="Улица")
    numb = models.CharField(max_length=64, verbose_name="Номер дома")

class Project(models.Model):
    manager = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name="Сотрудник")
    address = models.ForeignKey(Address, on_delete=models.PROTECT, verbose_name="Адрес")
    vis = models.DateField(verbose_name="Подписан дата", blank=True)
    accept = models.DateField(verbose_name="Принят дата", blank=True)

也许我需要一个逐步填写的表格

jyztefdp

jyztefdp1#

您可以根据自己的需要创建和自定义管理表单。例如,如果您为项目创建管理表单,并且希望将用户表单作为内联表单,则可以通过inlines轻松实现。
请参阅有关在表单中添加相关对象的文档。https://docs.djangoproject.com/en/4.1/intro/tutorial07/

8oomwypt

8oomwypt2#

如果您只需要管理控制台中的界面,我会按照Jamal的答案。
如果你想在自己的界面中创建一个自定义界面,我会这样做(未经测试):

# forms.py
class ProjectForm(forms.ModelForm):

    class Meta:
        model = Project
        fields = ['manager', 'vis', 'accept']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # When we're creating new instance
        if not self.instance.pk:
            self.address_form = AddressForm(
                data=kwargs.get('data'),
                files=kwargs.get('files'),
            )
        # When we're updating an existing instance
        else:
            self.address_form = AddressForm(
                instance=self.instance.address,
                data=kwargs.get('data'),
                files=kwargs.get('files'),
            )

class AddressForm(forms.ModelForm):

    class Meta:
        model = Address
        fields = ['street', 'numb']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # When we're creating new instance
        if not self.instance.pk:
            self.city_form = CityForm(
                data=kwargs.get('data'),
                files=kwargs.get('files'),
            )
        # When we're updating an existing instance
        else:
            self.city_form = CityForm(
                instance=self.instance.city,
                data=kwargs.get('data'),
                files=kwargs.get('files'),
            )

class CityForm(forms.ModelForm):

    class Meta:
        model = City
        fields = '__all__'
# views.py
class CreateProject(CreateView):
    model = Project
    form_class = ProjectForm
    template_name = 'project_form.html'

class UpdateProject(UpdateView):
    model = Project
    form_class = ProjectForm
    template_name = 'project_form.html'
# project_form.html

<form method="post">
    {% csrf_token %}

{#  The project form  #}
    {{ form.as_p }}

    <h2>Address</h2>
{#  The address form in the project form. Instead of the address field.  #}
    {{ form.address_form.as_p }}

    <h2>City</h2>
{#  The city form in the address form. Instead of the city field. #}
    {{ form.address_form.city_form.as_p }}

    <input type="submit" value="Save" />
</form>

另外,如果你碰巧使用django-crispy-forms包,请确保你没有呈现AddressFormCityForm中的表单标签。
PSPS.,如果你遇到了在同一页面上呈现的两个表单具有相同名称的属性的情况,你需要在表单的初始化器中使用prefix来命名这些属性。然而,你的问题不是这样的,所以我不想复杂化。

相关问题