Django CreateView get_initial 外键

lee*_*um1 3 python django django-models django-forms django-class-based-views

我有一个表单,我正在尝试使用该get_initial方法来设置外键。模型是

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)
Run Code Online (Sandbox Code Playgroud)

形式是

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()
            }
Run Code Online (Sandbox Code Playgroud)

视图是

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
Run Code Online (Sandbox Code Playgroud)

我得到的错误是

null value in column "client_id" violates not-null constraint
Run Code Online (Sandbox Code Playgroud)

看起来初始值没有传递给表单。如何将外键传递给表单?

Ala*_*air 5

使用隐藏字段不会阻止用户编辑值。如果要在视图中设置值,请从fields表单中将其删除:

class CardioRecordForm(forms.ModelForm):
        class Meta:
            model = CardioRecord
            fields = [
                      'run_dist',
                      'run_time',
                      ]
Run Code Online (Sandbox Code Playgroud)

然后在方法中设置表单实例的值form_valid

class CardioCreateView(CreateView):
    def form_valid(self, form):
        form.instance.client = self.request.user
        return super(CardioCreateView. self).form_valid(form)
Run Code Online (Sandbox Code Playgroud)

然后您可以删除您的get_initial方法。