2016-02-27 51 views
0

在下面的代码显示的示例中,是否可以使用LocalizacaoForm自动验证并创建EnderecoCoordenada的实例?通过Django中的外键字段验证多个相关对象ModelForm

我之所以要这样做,是为了尽可能地使用泛型视图,并且它们不能很好地工作(至少不是开箱即用),并且每个模型框架都有不同的功能视图。

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

有没有办法做我想要的,或者我应该坚持分别渲染每个表单?

#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' 

回答

1

您可以在LocalizacaoFormsave()方法创建的CoordenadaEndereco情况下,像这样:

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 
+0

就像一个魅力和看起来比如果我单独创建的每个窗体干净多了。 谢谢! –

相关问题