Opened 7 years ago

Last modified 7 years ago

#29160 closed Bug

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

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

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.

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 (1)

by Hameer Abbasi, 7 years ago

Attachment: sample_project.zip added

Sample project demonstrating the issue.

Note: See TracTickets for help on using tickets.
Back to Top