如何为反向外键关系创建内联表单集

Posted

技术标签:

【中文标题】如何为反向外键关系创建内联表单集【英文标题】:How to create an inline formset for a reverse foreign key relationship 【发布时间】:2015-09-23 13:13:40 【问题描述】:

我有一个如下的属性模型 =

class Property(models.Model):
    property_type = models.CharField(max_length=255, default='Apartment')
    specifications = models.CharField(max_length=255, default='Basic')
    built_up_area = models.FloatField(max_length=6, null=False, default=0)
    total_area = models.FloatField(null=False, default=0)
    number_of_bedrooms = models.CharField(max_length=3, default=1)
    number_of_bathrooms = models.CharField(max_length=3, default=1)
    number_of_parking_spaces = models.CharField(max_length=2, default=0)
    address_line_one = models.CharField(max_length=255, null=False)
    address_line_two = models.CharField(max_length=255, null=True, default=None)
    connectivity = models.CharField(max_length=255, default=None, null=True)
    neighborhood_quality = models.CharField(max_length=255, default=None,
                                            null=True)
    comments = models.CharField(max_length=255, default=None, null=True)
    city = models.ForeignKey('City')
    state = models.ForeignKey('State')
    pin_code = models.ForeignKey('PinCode')
    developer = models.ForeignKey('Developer', null=True, default=None)
    owner = models.ForeignKey('Owner', null=True, default=None)
    created_by = models.ForeignKey('custom_user.User')

    project = models.ForeignKey('Project')

    def __unicode__(self):
        return self.property_type

    class Meta:
        verbose_name_plural = 'Properties'

还有一个城市模型如下 -

class City(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(unique=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(City, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.name

现在我想制作一个表单,我可以在其中输入房产详细信息,并且在输入城市时,我可以输入城市名称,而不是从下拉列表中选择。

那么如何使用 inlineformset_factory 创建内联表单集来创建表单呢?

==编辑==

我尝试使用以下代码来创建表单集

CityFormset = inlineformset_factory(City, Property,
                                       fields=('city',),
                                       extra=0,
                                       min_num=1,
                                       can_delete=False)

【问题讨论】:

这似乎是 inlineformset_factory 的确切用例。你有什么问题? 如果 City 模型对 PropertyModel 有 fk,那么 inlineformset_factory 似乎可以正常工作,但反之则不然。 请不要在 20 分钟后找我帮忙。我有很多电话,并尽可能为 *** 做出贡献。必须等待几个小时才能得到答案并不罕见。 【参考方案1】:

您误解了内联表单集是什么。它用于编辑一对多关系的“多”方面:也就是说,给定 City 的父模型,您可以内联编辑属于该城市的各种属性。

您根本不希望表单集简单地编辑属性可以属于的单个城市。相反,将您的 Property 表单中的 city 字段覆盖为 TextField,然后创建一个新城市或在 clean_city 方法中查找现有城市。

class PropertyForm(forms.ModelForm):
    city = forms.TextField(required=True)

    class Meta:
        model = Property
        exclude = ('city',)

    def __init__(self, *args, **kwargs):
        super(PropertyForm, self).__init__(*args, **kwargs)
        if self.instance and not self.data:
            self.initial['city'] = self.instance.city.name

    def save(self, commit=True):
        city_name = self.cleaned_data['city']
        city, _ = City.objects.get_or_create(name=city_name)
        instance = self.save(commit=False)
        instance.city = city
        if commit = True:
            instance.save()
        return instance

【讨论】:

我收到以下表单验证错误“选择一个有效的选项。该选择不是可用的选择之一。' 您需要从表单中排除现有的城市字段。我已经更新了代码。 @DanielRoseman 谢谢丹尼尔,这让我明白了很多。不幸的是,即使我有类似的要求,它也对我不起作用。这是我的代码,如果你有机会请看一下。我已经强调了我收到的错误; dpaste.de/Gkcy#L65,78,79,86,94 上述方法对我不起作用,我做了一个噩梦来解决这个问题,但最终得到了答案。这里是; ***.com/questions/31907731/… 第一段应该在关于内联表单集的文档中。很难理解,在你了解了这个概念之后,很难理解如何在“一”端处理外键。

以上是关于如何为反向外键关系创建内联表单集的主要内容,如果未能解决你的问题,请参考以下文章

带有内联表单集的 Django 表单验证

将查询集传递给 django 内联表单中的外键字段

如何为表单选择做可访问的内联错误?

Django - 如何为模型的外键制作表单?

最初在 django 内联表单集中设置不同的外键值

Django内联表单集通过另一个模型在多对多关系中过滤