Opened 7 years ago

Last modified 7 years ago

#29160 closed Bug

Django ModelForm doesn't parse foreign keys in initial= kwarg. — at Version 2

Reported by: Hameer Abbasi Owned by: nobody
Component: Forms Version: 1.11
Severity: Normal Keywords: initial
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Hameer Abbasi)

Django forms don't parse foreign keys in the initial= kwarg. It gives a "NOT NULL constraint failed" even if the said data has been specified. This is inconvenient for forms since an instance can be specified but critical for formsets where it can't.

Relevant files:

models.py

Code highlighting:

from django.db import models


class BaseModel(models.Model):
    pass


# Create your models here.
class SimpleModel(models.Model):
    field = models.IntegerField(default=0)
    hidden_fk = models.ForeignKey(BaseModel, null=False)

forms.py

Code highlighting:

from django import forms

from . import models


class SimpleForm(forms.ModelForm):
    class Meta:
        model = models.SimpleModel
        fields = ['field']


SimpleFormset = forms.modelformset_factory(models.SimpleModel, fields=['field'], extra=3)  

views.py

Code highlighting:

from django import views
from django.template import loader
from django.http import HttpResponse

from . import forms
from . import models


# Create your views here.
class FormView(views.View):
    template = 'thing/form.html'

    def get(self, request):
        context = {'form': forms.SimpleForm()}
        template = loader.get_template(self.template)

        return HttpResponse(template.render(context, request))

    def post(self, request):
        base_model = models.BaseModel.objects.get(id=1)
        form = forms.SimpleForm(request.POST, initial={'hidden_fk': base_model})
        context = {'form': form}
        template = loader.get_template(self.template)

        simple_model = form.save(commit=False)
        simple_model.field = 1
        form.save()

        return HttpResponse(template.render(context, request))


class FormSetView(views.View):
    template = 'thing/formset.html'

    def get(self, request):
        context = {'formset': forms.SimpleFormset()}
        template = loader.get_template(self.template)

        return HttpResponse(template.render(context, request))

    def post(self, request):
        base_model = models.BaseModel.objects.get(id=1)

        formset = forms.SimpleFormset(
            request.POST,
            initial=[{'hidden_fk': base_model}] * forms.SimpleFormset.extra
        )

        context = {'formset': formset}
        template = loader.get_template(self.template)

        if formset.is_valid():
            formset.save()

        return HttpResponse(template.render(context, request))

Change History (3)

by Hameer Abbasi, 7 years ago

Attachment: sample_project.zip added

Sample project demonstrating the issue.

comment:1 by Hameer Abbasi, 7 years ago

Type: UncategorizedBug

comment:2 by Hameer Abbasi, 7 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top