【问题标题】:Django - empty form cannot be saved in databaseDjango - 空表单无法保存在数据库中
【发布时间】:2019-08-29 13:46:08
【问题描述】:

我有一个表单,用户指定 lawyer-spec 并将数据保存到数据库中。但是我收到一个错误

**null value in column "lawyer_spec" violates not-null constraint**

所以表单中的数据没有被正确处理。

编辑:

mthod form_invalid 打印空行,然后打印两个数字('pk' 和 'lawyer_id')

forms.py

class MakeAppointmentForm(forms.ModelForm):
    first_name = forms.CharField(required=True)

    class Meta:
        model = CalendarAppointmentsReserved
        fields = ['case']

    def __init__(self, *args, lawyer_id, pk, **kwargs):
        super().__init__(*args, **kwargs)
        lawyer_id_from_kwargs = lawyer_id
        lawyer_specs = LawyersSpec.objects.filter(lawyer=lawyer_id_from_kwargs)

        choices = [(spec.lawyer_spec, dict(CASES)[spec.lawyer_spec]) for spec in lawyer_specs]

        self.fields['case'].choices = choices

views.py

@method_decorator(user_required, name='dispatch')
class MakingAppointmentView(CreateView):
    template_name = "make_appointment.html"
    form_class = TestPy.forms.MakeAppointmentForm
    model = TestPy.models.CalendarAppointmentsReserved

    def get_form_kwargs(self):
        pk = self.kwargs.get('pk')
        self.kwargs = super().get_form_kwargs()

        self.kwargs = {'lawyer_id': self.request.session['lawyer_id'], 'pk': pk}

        self.kwargs.update(self.kwargs)  # self.kwargs contains all url conf params
        return self.kwargs


    def form_invalid(self, form):
        print(form.errors)
        print(self.kwargs.get('pk'))
        print(self.kwargs.get('lawyer_id'))
        return redirect('home')


    def form_valid(self, form):
        calendar_model = TestPy.models.CalendarFreeSlot.objects.get(pk=self.kwargs.get('pk'))
        calendar_model.is_available = False
        calendar_model.save()

        self.object = form.save(commit=False)
        self.object.users_id = self.request.user
        self.object.calendar_free_id = calendar_model
        self.request.session['free_calendar_id'] = calendar_model.pk
        self.request.session['lawyer_id'] = calendar_model.lawyer_id.pk

        self.object.save()
        return redirect('home')

models.py

class LawyersSpec(models.Model):
    lawyer = models.ForeignKey('MyUser', on_delete=models.PROTECT)
    lawyer_spec = models.SmallIntegerField(choices=CASES)

class CalendarAppointmentsReserved(models.Model):
    calendar_free_id = models.ForeignKey('CalendarFreeSlot', on_delete=models.PROTECT) 
    users_id = models.ForeignKey('MyUser', on_delete=models.PROTECT) 
    case = models.SmallIntegerField(choices=CASES)

如何正确处理数据并保存在数据库中?

【问题讨论】:

  • 查看 get_form_kwargs() 方法中的逻辑。这是行不通的。
  • 为什么?有什么问题?如果我将self.kwargs.get 放在super() 之后,则它没有“pk”值
  • self.kwargs = super() 和下一行 self.kwargs = {..}。与写a = 1; a = 2 相同。你觉得a的价值是多少?
  • 最后一个问题,如何绑定表单?因为我读过我的问题是未绑定的形式,但我不知道绑定它,而它是动态生成的?
  • 它在 form.data 不是 None 时被绑定,当你传递数据时会发生这种情况。在上面的代码中,您删除了通过 super().get_form_kwargs() 获得的所有表单 kwargs,其中包含数据,这就是您的表单没有被绑定的原因。只需修复那部分代码,您的表单就会被绑定。

标签: django django-models django-forms


【解决方案1】:

你在这里犯了一个严重的错误:

  • 您的 CreateView 用于 CalendarAppointmentsReserved 模型
  • 您的表单适用于LawyersSpec 模型

这是不可能的,因为模型A 的创建视图期望同一模型AModelForm

将您的表单更改为:

class MakeAppointmentForm(forms.ModelForm):
    first_name = forms.CharField(required=True)

    class Meta:
        model = CalendarAppointmentsReserved
        fields = ['case']

    def __init__(self, *args, lawyer_id, pk, **kwargs):
        super().__init__(*args, **kwargs)
        lawyer_specs = LawyersSpec.objects.filter(lawyer=lawyer_id)
        choices = [(spec.lawyer_spec, dict(CASES)[spec.lawyer_spec]) for spec in lawyer_specs]
        self.fields['case'].choices = choices

现在在您看来,您不再需要分配 self.object.case

您还通过直接为其分配字典来重置 get_form_kwargs() 方法中的 self.kwargs。然后self.kwargs.update(self.kwargs) 什么都不做,你正在用它自己更新一个字典。所以你在这里丢失了所有的 POST 数据。正确的做法是这样的:

def get_form_kwargs(self):
    form_kwargs = super().get_form_kwargs()  # don't mess up self.kwargs
    pk = self.kwargs.get('pk')
    form_kwargs.update({'lawyer_id': self.request.session['lawyer_id'], 'pk': pk})
    return form_kwargs

【讨论】:

  • 我已经改变了它,现在错误说 "case" 列中的空值违反了非空约束细节:失败行包含 (29, null, 21, 3)。
  • 你能在你的 form_valid() 方法中设置一个断点并检查 form.cleaned_data 和 self.request.POST 吗? (如果你不知道如何设置断点,也可以打印出来,但我建议你尽快学习,因为它会让你的生活变得更轻松)
  • 你确实删除了self.object.case = self.object.spec这一行?
  • 我删除了self.object.case = self.object.spec
  • 和? self.request.POST 是什么?
猜你喜欢
  • 2018-03-16
  • 1970-01-01
  • 2021-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
  • 2020-10-07
相关资源
最近更新 更多