如何创建反向外键关系的内联格式集 [英] How to create an inline formset for a reverse foreign key relationship

查看:116
本文介绍了如何创建反向外键关系的内联格式集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个属性模型如下=

  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('状态')
pin_code = models.ForeignKey('PinCode')
developer = models.ForeignKey('Developer',null = True,default = None)
owner = models.ForeignKey('所有者,null = True,默认=无)
created_by = models.ForeignKey('custom_user.User')

project = models.ForeignKey('Project')

def __unicode __(self):
return self.property_type

class Meta:
verbose_name_plural ='属性'

和城市模型如下 -

  class City 
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)


解决方案

你误会了内联表单。它是为了编辑一对多关系的许多一面:也就是说,给予城市的父模型,您可以编辑属于该城市的各种属性。



您根本不需要一个表单来简单地编辑属性可以属于的单个城市。相反,将您的属性窗体中的 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)
如果self.instance而不是self.data:
self.initial ['city'] = self.instance.city.name

def save(self,commit = True):
city_name = self.cleaned_data ['city']
city,_ = City。 object.get_or_create(name = city_name)
instance = self.save(commit = False)
instance.city = city
如果commit = True:
instance.save()
返回实例


I have a Property Model as follows =

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'

And a City model as follows -

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

Now I want to make a single form where I can enter the Property details and while entering the city, I can enter the name of the city instead of selecting from the dropdown list.

So how do I create the inline formset using the inlineformset_factory to create the form?

==EDIT==

I've tried to use the following code to create the formset

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

解决方案

You've misunderstood what an inline formset is. It's for editing the "many" side of a one-to-many relationship: that is, given a parent model of City, you could edit inline the various Properties that belong to that city.

You don't want a formset at all to simply edit the single City that a property can belong to. Instead, override the city field within your Property form to be a TextField, and either create a new City or find an existing one in the clean_city method.

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

这篇关于如何创建反向外键关系的内联格式集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆