使用模型表单保存两个相关模型

时间:2015-06-18 09:20:12

标签: python django django-models django-forms

以下是两个模型 - Property和Developer:

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)
    total_area = models.FloatField(null=False)
    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, default=None)
    city = models.CharField(max_length=255, null=False)
    state = models.CharField(max_length=255, null=False)
    pin_code = models.CharField(max_length=20, null=False)
    developer = models.ForeignKey('Developer')

    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)

    def __unicode__(self):
        return self.property_type


class Developer(models.Model):
    name = models.CharField(max_length=255, null=False)

    def __unicode__(self):
        return self.name

以下是相应的表格:

class PropertyForm(ModelForm):
    developer = forms.CharField()

    class Meta:
        model = Property
        fields = [
            'built_up_area',
            'total_area',
            'number_of_bedrooms',
            'number_of_bathrooms',
            'number_of_parking_spaces',
            'address_line_one',
            'address_line_two',
            'city',
            'state',
            'pin_code',
        ]
        widgets = {
            'number_of_bedrooms': forms.Select(
                choices=((1, 1,), (2, 2), (3, 3)), ),
            'number_of_bathrooms': forms.Select(
                choices=((1, 1,), (2, 2), (3, 3)), ),
            'number_of_parking_spaces': forms.Select(
                choices=((1, 1,), (2, 2), (3, 3)), ),
            'developer': forms.TextInput(),
        }

    def __init__(self, *args, **kwargs):
        super(PropertyForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.fields['address_line_two'].required = False,
        self.helper.layout = Layout(
            AppendedText('built_up_area', 'sq ft'),
            AppendedText('total_area', 'sq ft'),
            'number_of_bedrooms',
            'number_of_bathrooms',
            'number_of_parking_spaces',
            'address_line_one',
            'address_line_two',
            'city',
            'state',
            'pin_code',
            'developer',
            ButtonHolder(
                Submit('Submit', 'submit', css_class='btn-block')
            )
        )

    def save(self, commit=True):
        developer = self.cleaned_data['developer']
        developer, created = Developer.objects.get_or_create(name=developer)
        self.instance.developer = developer

        return super(PropertyForm, self).save()

使用单一表单保存相关对象的更好方法是什么?

这里使用的是formset吗?我读过它们但却无法得到它。

1 个答案:

答案 0 :(得分:0)

我不确定这是最优的,但有一点要记住,你的html-可以包含几个django形式。在某种程度上,将django表单视为具有附加功能的表单字段集合(验证等等)可能是有用的。 因此,您可以拥有两个常规的ModelForms。一个用于属性,一个用于开发人员。在你看来你实例化两者并将它们交给你的模板。

所述模板现在可能包含以下内容:

<form blahblub....>
Properties:
{{ propertyform.as_p }}

Developer:
{{ developerform.as_p }}
</form>

现在,在发布后,您的视图可以将POST数据绑定到以下每个djangoforms:

propertyform = PropertyForm(request.POST)
developerform = DeveloperForm(request.POST)
在您的视图中,您可以像往常一样验证表单。 您可以添加一些自定义逻辑,而不是仅仅调用Form.save(),如果您想先在oder中处理developerform以保存它,然后在后处理属性表单中继续将创建的对象用作FK。

关于(模型)Formsets:如果你想为一个普通开发者创建几个属性,这可能是有用的。但是一旦基础工作,你就可以处理它了:)