Django: Как я могу использовать inlineformset для сохранения нескольких форм, которые имеют один и тот же FK, как и другой объект, создаваемый на той же странице формы?

У меня есть две модели Animal и Gene_Animal_Bridge. У меня есть страница с формой, которая позволяет пользователю добавить новое животное в базу данных и прикрепить все гены, которые у него есть. Гены хранятся в Gene_Animal_Bridge, который содержит FK животного, которому оно принадлежит, и FK гена, который хранится в модели GeneInfo. Все работает нормально, но когда дело доходит до итерации по набору форм, сохраняется только 1 ген, а все остальные формы генов, добавленные на странице, не сохраняются.

Models.py

from django.db import models
import datetime


class Animal(models.Model):
    animal_id = models.AutoField(primary_key=True, editable=False, null=False)
    gender = models.CharField(max_length=6, choices=(('m','male'), ('f','female')), null=True)
    name = models.CharField(max_length=14)
    description = models.CharField(max_length=75,blank=True, null=False)
    dob = models.DateField(default=datetime.date.today, blank=True, null=True)
    purchase_date = models.DateField(default=datetime.date.today, blank=True, null=True)
    image = models.ImageField(blank=True, null=True)
    prey_type = models.CharField(max_length=20,choices=(('1','2XL Multi'),('2','Large Weaner'),('3','Live Multi'),('4','Small Rat'),('5','Small Weaner')),blank=True, null=True)
    last_feed = models.DateField(default=datetime.date.today, blank=True, null=True)
    last_shed = models.DateField(default=datetime.date.today, blank=True, null=True)
    weight = models.IntegerField(blank=True, null=True)

class GeneInfo(models.Model):
    gene_id = models.AutoField(primary_key=True, editable=False, null=False)
    gene_name = models.CharField(max_length=20, null=False)
    type = models.CharField(max_length=20,choices=(('1','pos het'),('2','het'),('3','visual'),('4','co-dominant'),('5','super'),('6','dominant')),null=False)

    def __str__(self):
        return (self.gene_name)
    

class Gene_Animal_Bridge(models.Model):
    animal_id = models.ForeignKey(Animal, on_delete=models.CASCADE, related_name="bridge_animal_id", null=True)
    gene_id = models.ForeignKey(GeneInfo, on_delete=models.CASCADE, related_name="bridge_gene_id", null=True)
    

class Breeding(models.Model):
    sire_id = models.ForeignKey(Animal, on_delete=models.CASCADE, related_name="breeding_sire_id", null=True)
    dame_id = models.ForeignKey(Animal, on_delete=models.CASCADE, related_name="breeding_dame_id", null=True)
    date_bred = models.DateField(default=datetime.date.today, blank=True, null=True)
    visual_lock = models.CharField(max_length=6, choices=(('y','yes'), ('n','no')), blank=True, null=True)

class Clutch(models.Model):
    clutch_id = models.AutoField(primary_key=True,  null=False)
    sire_id = models.ForeignKey(Animal, on_delete=models.CASCADE, related_name="clutch_sire_id", null=True)
    dame_id = models.ForeignKey(Animal, on_delete=models.CASCADE, related_name="clutch_dame_id", null=True)
    eggs_num = models.IntegerField(blank=True)
    lay_date = models.DateField(default=datetime.date.today, blank=True, null=True)
    hatch_date = models.DateField(default=datetime.date.today, blank=True, null=True)

forms.py

from django import forms
from django.forms import ModelForm
from datetime import datetime 
from .models import Animal, Gene_Animal_Bridge, GeneInfo
from django.forms import ModelChoiceField

class MyModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return "My Object #%i" % obj.id

class NewAnimal(ModelForm):
   class Meta:
       model = Animal
       exclude = ('image',)

       widgets = {
            'dob': forms.DateInput(attrs={'type': 'date', 'max': datetime.now().date()}),
            'purchase_date': forms.DateInput(attrs={'type': 'date', 'max': datetime.now().date()}),
            'last_feed': forms.DateInput(attrs={'type': 'date', 'max': datetime.now().date()}),
            'last_shed': forms.DateInput(attrs={'type': 'date', 'max': datetime.now().date()}),
            'weight': forms.NumberInput(attrs={'min': 0})
        }

class AddGene(ModelForm):
  
    class Meta:
        model = Gene_Animal_Bridge
        fields = ('gene_id',)

views.py

from django.forms import inlineformset_factory
from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect
from django.urls import reverse
from .forms import AddGene, NewAnimal, GeneInfo
from .models import Animal, Gene_Animal_Bridge

def home(request):
    return render(request, 'base/home.html')

def collection(request):
    animal_list = Animal.objects.all()
    return render(request, 'base/collection.html', {'animal_list':animal_list})

def newanimal(request):
    add_gene_formset = inlineformset_factory(Animal,Gene_Animal_Bridge, form=AddGene, extra=1)
    
    animal_form = NewAnimal()
    formset = add_gene_formset
    if request.method =="POST":
        animal_form = NewAnimal(request.POST or None)
        formset = add_gene_formset(request.POST or None)
        if request.method == "POST":
            print(request.POST)
        if animal_form.is_valid() and formset.is_valid():
         instance = animal_form.save(commit=False)
         instance.save()
         gene = formset.save(commit=False)
         for form in gene:
            
            form.animal_id = instance
            form.save()
         
         return redirect(reverse('collection'))
    context = {'animal_form': animal_form,'formset': formset}
    return render(request, 'base/newanimal.html', context   )

P.S. У меня нет большого опыта кодирования, поэтому я не знаком со многими понятиями.

Вернуться на верх