【问题标题】:Django auto assign value to foreign key when a form is submitted?提交表单时Django自动为外键赋值?
【发布时间】:2019-03-08 07:33:26
【问题描述】:

我想在用户提交创建表单时自动将公司名称呈现到数据库中...

这是我的模型:

 class company(models.Model):
    User = models.ForeignKey(User,related_name="Company_Owner",on_delete=models.CASCADE,null=True,blank=True)
    Name = models.CharField(max_length=50,blank=False)

class group1(models.Model):
    User = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True)
    group_Name = models.CharField(max_length=32)
    Company = models.ForeignKey(company,on_delete=models.CASCADE,null=True,blank=True,related_name='Company_group')

这就是我在views.py中尝试做的事情:

class group1CreateView(LoginRequiredMixin,CreateView):
    form_class  = group1Form
    template_name = "accounting_double_entry/group1_form.html"

    def form_valid(self, form):
        form.instance.User = self.request.user
        form.instance.Company = company
        return super(group1CreateView, self).form_valid(form)

但是得到了这个错误:

ValueError: Cannot assign "<class 'company.models.company'>": "group1.Company" must be a "company" instance.

它适用于用户,但不适用于公司..

谁能告诉我我做错了什么???

谢谢...

【问题讨论】:

  • 请分享完整代码
  • Company 是我在 group1 模型中给出的字段的名称...而 company 是通过外键与 group1 链接的模型...
  • form.instance.Company = company,这个company 来自哪里?
  • 我已经编辑了我的代码...
  • 来自公司模式

标签: python django django-models django-forms django-views


【解决方案1】:

错误可能在这一行

form.instance.Company = company


这里的 company 看起来像 Python class,它应该是一个 company 类的实例


所以,使用对象/实例作为

company_obj = company.objects.create(.....) # created a ne object
form.instance.Company = company_obj



company_obj = company.objects.get(id=someid) # fetch new object from db
form.instance.Company = company_obj



除了例外,我们建议您在代码/项目中遵循PEP8 naming convetions

【讨论】:

【解决方案2】:

使用查询来获取您需要的公司对象,而不是 c=company.objects.get(id=1)

def form_valid(self, form):
    form.instance.User = self.request.user
    c=company.objects.get(id=1)
    form.instance.Company = c
    return super(group1CreateView, self).form_valid(form)

【讨论】:

  • 您需要用现有的公司对象填充公司还是需要在用户输入公司名称时创建一个新对象?
【解决方案3】:

@JPG 的回答是正确的。我会详细解释。

首先,您的班级名称命名错误。类名遵循 CamelCase,python 中的首字母大写。违反这一点会导致类似这样的错误,您将类名与实例名混淆。

【讨论】:

  • 不幸的是,我昨天已经建议重命名(但可能在其他一些答案中,stackoverflow.com/questions/52603288/…),但不幸的是,该建议没有被考虑在内。
  • @Wliiem Van Onsem 我已将您的建议纳入我的主要项目...这只是我所做的一个实践项目,因为我现在是一名学习者...
  • @NiladryKar:但是上面的经验(两天两道题),其实应该让你断定这样做不好。就像他们说的:“20% 的开发时间应该用于重构”。是的,重构需要时间和汗水。但如果不这样做,最终情况只会变得更糟。
  • @NiladryKar 你应该通过这个,PEP8 naming conventions
  • 是的,我肯定不会再犯同样的错误,并且还更新了我的练习代码....谢谢大家
【解决方案4】:

你需要这样的东西:

class group1CreateView(LoginRequiredMixin,CreateView):
    form_class  = group1Form
    template_name = "accounting_double_entry/group1_form.html"

    def form_valid(self, form):
        form.instance.User = self.request.user
        # form.instance.Company = company
        form.instance.Company = company.objects.get(pk='something') # OR
        # form.instance.Company = company.objects.create(stuff='stuff')
        return super(group1CreateView, self).form_valid(form)

类名也应以大写(Pascal Case)开头,其属性应以小写(snake_case)开头。这是一种常见的做法,请遵循它以避免混淆

【讨论】:

  • 我可以这样做'c = company.objects.get(pk=self.kwargs['pk'])'
  • 我不这么认为。您应该做的是让用户在您的表单中创建或选择公司。
  • 是的,我也在想这个……谢谢@Vaibhav Vishal
猜你喜欢
  • 2016-01-08
  • 2020-12-30
  • 2018-10-28
  • 1970-01-01
  • 2019-11-16
  • 2018-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多