簡體   English   中英

如何使用 Django 中的兩個 ForeignKey 字段在 ModelForm 中保存 model

[英]How to save a model in ModelForm with two ForeignKey fields in Django

有一個 model Listaflor 鏈接到 Estados,另一個 model 名為 Flora2Estado,我用 ModelMultipleChoiceField 制作了一個表格。 它成功保存到 Listaflor 但沒有保存到 Flora2Estado,我該怎么辦?

forms.py

class FloForm(forms.ModelForm):
    familia = forms.ModelChoiceField(queryset=Familia.objects.all().order_by('familia_nome').filter(aprovado=1))
    Especie = forms.CharField(label="Nome da espécie*")
    estados = forms.ModelMultipleChoiceField(queryset=EstadosM.objects.all().order_by('nome_abbr'))
    class Meta:
        model = Listaflor
        ordering = ["estados",]
        fields = ['Especie','estados']

視圖.py

def CreateFlo(request):
    form = FloForm()
    if request.method == 'POST':
        form = FloForm(request.POST)
        if form.is_valid():
            Listaflor = form.save(commit=False)
            Flora2Estado = form.save(commit=False)
            Listaflor.save()
            Flora2Estado.save()
  
    return render(request,'accounts/enviar_flora.html')

模型.py

class Flora2Estado(models.Model):
    estado = models.ForeignKey(EstadosM, models.CASCADE)
    especie = models.ForeignKey(Listaflor, models.CASCADE)
    flora2estado = models.AutoField(primary_key=True)
    class Meta:
        managed = False
        db_table = 'flora2estado'
        unique_together = (('estado', 'especie'),)

歡迎任何關於幫助我做出更好帖子的提示,祝你有美好的一天!

View.py 更新:返回驗證錯誤!

def CreateFlo(request):    
    EstadosInlineFormSet  = inlineformset_factory(Listaflor, Flora2Estado, form=Flo2Form)
    Form = FloForm(request.POST)
    storeForm = FloForm(request.POST)
    if Form.is_valid():
        new_store = storeForm.save()
        florInlineFormSet = EstadosInlineFormSet(request.POST or None, request.FILES or None, instance=new_store)

        if florInlineFormSet.is_valid():
            florInlineFormSet.save()
    context = {'form': Form}
    return render(request,'accounts/enviar_flora.html', context)

模型.py:

class Flora2Estado(models.Model):
    estado = models.ForeignKey(EstadosM, models.CASCADE)
    especie = models.ForeignKey(Listaflor, models.CASCADE)
    flora2estado = models.AutoField(primary_key=True)
    class Meta:
        managed = False
        db_table = 'flora2estado'
        unique_together = (('estado', 'especie'),)
class Listaflor(models.Model):
    especie_id = models.AutoField(primary_key=True)
    familia = models.ForeignKey(Familia, models.DO_NOTHING, db_column='familia_id', blank=True, null=True)
    Especie = models.CharField(db_column='especie', max_length=255, blank=True, null=True) 

我試過這個:

def CreateFlo(request):
    form = FloForm()
    if request.method == 'POST':
        form = FloForm(request.POST)
        if form.is_valid():
            listafor = form.save()
            estados = form.cleaned_data.get('estados')
            for estado in estados:
                Flora2Estado.objects.create(especie=listafor, estado= estado)
    texto="..."
    context = {'floForm': form,'texto': texto}
    return render(request, 'accounts/enviar_flora.html', context)

得到錯誤:

django.db.utils.IntegrityError: (1062, "Duplicate entry '18-3256' for key 'PRIMARY'")

錯誤!

這是因為您在這里明確提到Listaflor

class Meta:
    model = Listaflor

即使您已將其更改為

class Meta:
    model = Flora2Estado

您不能像這樣在Flora2Estado中保存ForeignKey字段。

讓我們看一下使用ForeignKey保存ModelForm

您可以指定兩個唯一前綴來區分 forms:

form1 = FloForm(prefix='form-1')
form2 = FloForm(prefix='form-2')
if request.method == 'POST':
    form1 = FloForm(request.POST,prefix='form-1')
    form2 = FloForm(request.POST,prefix='form-2')
    if form.is_valid():
        Listaflor = form1.save(commit=False)
        Flora2Estado = form2.save(commit=False)
        Listaflor.save()
        Flora2Estado.save()

您可以嘗試從表單的cleaned_data中提取estados ,如下所示:

def CreateFlo(request):
    form = FloForm()
    if request.method == 'POST':
        form = FloForm(request.POST)
        if form.is_valid():
            listafor = form.save()
            estados = form.cleaned_data.get('estados')
            for estado in estados:
                Flora2Estado.objects.create(especie=listafor, estado= estado)
            # or you can use bulk_create: https://docs.djangoproject.com/en/3.0/ref/models/querysets/#bulk-create
  
    return render(request,'accounts/enviar_flora.html')

更新

真的很難說是哪個 model 出錯了,但我的假設是 Listaflor model。 您可能有一個默認值為“18-XXXX”的主鍵字段。 當您使用 FloForm 創建 Listaflor 實例時,您沒有提供任何主鍵值,因此它將默認值作為主鍵,從而引發 Integrity 錯誤。 要解決此問題,您可以使用動態 function生成主鍵的值或使用UUIDField / AutoField自動生成主鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM