1

There is a model Listaflor linked to Estados with another model named Flora2Estado, i made a form with ModelMultipleChoiceField. It saves successfully into Listaflor but nothing into the Flora2Estado, what can i do about this?

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

views.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')

models.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'),)

Any tips on helping me making a better post is welcome, have a good day!

View.py updated: returning Validation error!

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)

models.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) 

I tried this:

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)

got the error:

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

error!

Kari dime
  • 78
  • 11

3 Answers3

1

It is because you have clearly mentioned Listaflor here:

class Meta:
    model = Listaflor

Eventhough if you've changed it to

class Meta:
    model = Flora2Estado

You can't save the ForeignKey fields in Flora2Estado like that.

Let's have a look at this on Saving Django ModelForm with a ForeignKey

Siva Sankar
  • 1,672
  • 1
  • 9
  • 16
1

You can specify two unique prefixes to differentiate between the 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()
The Mask
  • 390
  • 3
  • 17
1

You can try to extract out the estados from form's cleaned_data, like this:

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

Update

It is really hard to tell for which model you are getting the error, but my assumption is Listaflor model. It is a possibility that you have a primary key field in which default value is “18-XXXX”. When you are creating Listaflor instance using the FloForm, you are not providing any primary key value, so it is taking the default value as primary key, hence throwing Integrity error. To solve this you can either use a dynamic function to generate the value of primary key or use UUIDField/AutoField to generate primary key automatically.

ruddra
  • 50,746
  • 7
  • 78
  • 101
  • got: IntegrityError at /enviar_flora/ (1062, "Duplicate entry '18-3223' for key 'PRIMARY'") – Kari dime Jan 30 '21 at 22:32
  • 1
    Can you please add the full error stack trace on the question? Also for which model do you get the error? – ruddra Jan 31 '21 at 04:48
  • Your awnser got me the closest to the solution! but i still can't get it to work, i posted the error in the question!! – Kari dime Feb 02 '21 at 19:47
  • thank you, i'm getting the error for flora2estados, i looked for the key in the db. the problem is, it already uses autofield, i will try to use the dynamic function. – Kari dime Feb 03 '21 at 04:35
  • 1
    did you run migrations and migrate commands? – ruddra Feb 03 '21 at 06:08
  • 1
    The error says it is due to primary key. Can you please try to create a Flora2Estado instance in django shell to see if this problem occurs or not? – ruddra Feb 03 '21 at 09:38
  • ,succesfully added >>>obj0 = Listaflor.objects.create(especie_id=9999, Especie="teste") >>> obj = EstadosM.objects.create(estado_nome="teste, nome_abbr="tt") >>> obj2 = Flora2Estado.objects.create(estado=obj, especie=obj0) – Kari dime Feb 03 '21 at 18:59
  • yes!,the whole models are working, i can add items on the django admin without a hitch – Kari dime Feb 03 '21 at 19:01
  • 1
    Okay, that means the problem is somewhere in the code. I will try to debug or reproduce it in my local machine and let you know later today or tomorrow – ruddra Feb 03 '21 at 19:38
  • thank you very much!! here's the bounty :) – Kari dime Feb 03 '21 at 20:28
  • 1
    Hi, I could not reproduce the issue, but I found out that the `Flora2Estado`'s table is not managed by django ORM, meaning all the changes there has to be made manually(because of `managed=False` in model meta). So, auto field might not work if it was not migrated into DB table, meaning `flora2estado` could be something other than a autofield. – ruddra Feb 05 '21 at 13:25
  • 1
    After I migrated properly in DB, all the code seems to be working just fine and generating `Flora2Estdao` instances from form.save(). – ruddra Feb 05 '21 at 13:25
  • Hello! i changed flora2estado managed to true without success... – Kari dime Feb 05 '21 at 19:29
  • actually, the error steems from listaflor, it creates things in the db but throws the error anyway – Kari dime Feb 05 '21 at 19:38
  • 1
    To fix the migration, what I did was drop flora2estado table from DB, comment out Flora2Estado code, then ran makemigration and ‘./manage.py migrate —fake’, then undo the commented out part, ran migrations and migrate command. I used the same code as yours, I just used some simpler models for Famila and EstadioM. – ruddra Feb 05 '21 at 20:01
  • 1
    If listaflor is throwing error then my assumption was correct in the first place, please see if the migration is managed by Django or not, if not please use the procedure mentioned above – ruddra Feb 05 '21 at 20:03
  • now lista flora and flora2estado managed=True!! still got the error – Kari dime Feb 05 '21 at 23:00
  • strange because it create in the db the key that shows "duplicate" like it's trying to create two listaflors – Kari dime Feb 05 '21 at 23:02
  • isn't the problem in the listaflor = form.save()? should't it just send the especie_id to the newly created instance? – Kari dime Feb 05 '21 at 23:08
  • https://stackoverflow.com/questions/66071889/django-duplicate-key-when-trying-to-send-a-form-with-foreign-key – Kari dime Feb 05 '21 at 23:34
  • For now, you can add a hack solution which is to add a try catch. But still, this is not a real solution. Unfortunately the code given here is working in my DB. Can you maybe try with a new DB to see if this error occurs or not. For fresh setup, you should delete the migration files from apps directory and then run makemigrations and migrate command. – ruddra Feb 06 '21 at 08:59