【问题标题】:Validate multiple related objects through foreign key field in Django ModelForm通过Django ModelForm中的外键字段验证多个相关对象
【发布时间】:2016-06-10 11:16:42
【问题描述】:

在下面代码所示的示例中,是否可以使用LocalizacaoForm 自动验证和创建Endereco 和Coordenada 的实例?

我想这样做的原因是我可以尽可能多地使用通用视图,但在每个视图不止一个 ModelForm 的情况下它们不能很好地工作(至少不是开箱即用的) .

在应用程序中,我想渲染一个LocalizacaoForm 并显示来自Endereco 和Coordenada 的字段。到目前为止我所做的似乎并没有解决它,因为self.fields.update(fields_for_model(Coordenada)) 只创建输入字段,而不是Coordenada 的实际实例。因此,我得到了对象 coordenada 的django NOT NULL constraint failed id。

有没有办法做我想做的事,还是我应该坚持单独渲染每个表单?

#models.py
class Coordenada(models.Model):
    latitude = models.FloatField()
    longitude = models.FloatField()
    altitude = models.FloatField()
    erro_horizontal = models.FloatField()

class Endereco(models.Model):
    cep = models.IntegerField()
    uf = models.CharField(max_length=2)
    localidade = models.CharField(max_length=50)  # nome da cidade
    # other fields...

class Localizacao(models.Model):
    endereco = models.OneToOneField(Endereco)
    coordenada_geografica = models.ForeignKey('Coordenada')

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

    def __init__(self, instance=None, *args, **kwargs):
        super(LocalizacaoForm, self).__init__(instance=instance, *args, **kwargs)
        # Retrieve the fields from Endereco and Coordenada model and update the fields with it
        self.fields.update(fields_for_model(Endereco))
        self.fields.update(fields_for_model(Coordenada))

    class Meta:
        model = Localizacao
        exclude = ('endereco', 'coordenada_geografica')

#views.py
class LocalizacaoCreateView(generic.CreateView):
    model = Localizacao
    form_class = LocalizacaoForm
    template_name = 'localizacao_create_form.html'

【问题讨论】:

    标签: django django-models django-forms modelform


    【解决方案1】:

    您可以在LocalizacaoForm 的save() 方法中创建Coordenada 和Endereco 的实例,如下所示:

    class LocalizacaoForm(forms.ModelForm):
    
        # The rest of the form ...
        # ...
    
        def save(self, commit=False):
            localizacao = super(LocalizacaoForm, self).save(commit=False)
    
            # create an instance of Coordenada
            coordenada = Coordenada.objects.create(
                            latitude=self.cleaned_data['latitude'],
                            longitude=self.cleaned_data['longitude'],
                            altitude=self.cleaned_data['altitude'],
                            erro_horizontal=self.cleaned_data['erro_horizontal']
                        )
    
            # create an instance of Endereco
            endereco = Endereco.objects.create(
                            cep=self.cleaned_data['cep'],
                            uf=self.cleaned_data['uf'],
                            localidade=self.cleaned_data['localidade'],
                        )
    
            # add those instances to localizacao
            localizacao.coordenada_geografica = coordenada
            localizacao.endereco = endereco
    
            if commit:
                localizacao.save()
            return localizacao
    

    【讨论】:

    • 工作起来就像一个魅力,看起来比我单独创建每个表单要干净得多。谢谢!
    猜你喜欢
    • 2018-07-03
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 2018-08-14
    • 2020-10-08
    • 1970-01-01
    • 2011-01-14
    • 2015-10-01
    相关资源
    最近更新 更多