leelum1
leelum1

Reputation: 1254

Django CreateView get_initial Foreign Key

I have a form and I am trying to use the get_initial method to set a foreign key. The model is

class CardioRecord(models.Model):
    date_uploaded = models.DateField(auto_now=True)
    client = models.ForeignKey(User, on_delete=models.CASCADE)
    run_dist = models.FloatField(blank=True, null=True)
    run_time = models.FloatField(blank=True, null=True)

The form is

class CardioRecordForm(forms.ModelForm):
        class Meta:
            model = CardioRecord
            fields = [
                        'client',
                      'run_dist',
                      'run_time',
                      ]
            labels = {
                'run_dist': 'Distance (km)',
                'run_time': 'Time (min)',
            }
            widgets = {
                'client': forms.HiddenInput()
            }

The view is

class CardioCreateView(CreateView):
    model = CardioRecord
    form_class = CardioRecordForm
    template_name = 'training/cardio_form.html'

    def get_initial(self):
        initial = super(CardioCreateView, self).get_initial()
        initial['client'] = self.request.user.pk
        return initial

and the error that I am getting is

null value in column "client_id" violates not-null constraint

which looks like the initial value is not being passed to the form. How do I pass the Foreign Key to the form?

Upvotes: 3

Views: 2866

Answers (1)

Alasdair
Alasdair

Reputation: 309099

Using a hidden field doesn't stop the user from editing the value. If you want to set the value in the view, then remove it from fields in the form:

class CardioRecordForm(forms.ModelForm):
        class Meta:
            model = CardioRecord
            fields = [
                      'run_dist',
                      'run_time',
                      ]

Then set the value on the form's instance in the form_valid method:

class CardioCreateView(CreateView):
    def form_valid(self, form):
        form.instance.client = self.request.user
        return super(CardioCreateView. self).form_valid(form)

You can then remove your get_initial method.

Upvotes: 5

Related Questions