更新 Django 中现有的 M2M 关系
Posted
技术标签:
【中文标题】更新 Django 中现有的 M2M 关系【英文标题】:Update existing M2M relationship in Django 【发布时间】:2014-03-02 03:48:54 【问题描述】:我正在尝试保存客户记录的现有实例。它的模型对车辆模型具有 M2M(因为客户可以多辆车)。在这里阅读了几个问题/答案后,我仍然不知道如何解决这个问题。
客户模型:
class Customer(models.Model):
vehicle_id = models.ManyToManyField(VehicleSale)
name = models.CharField(max_length=40, blank=True, db_index=True, null=True,
verbose_name='name')
lic = models.CharField(max_length=20, blank=True, db_index=True, null=True,
verbose_name='license')
addr = models.CharField(max_length=40, blank=True, null=True, verbose_name='address')
city = models.CharField(max_length=15, blank=True, null=True, verbose_name='city')
state = models.CharField(max_length=2, blank=True, null=True, verbose_name='state')
zip = models.CharField(max_length=10, blank=True, null=True, verbose_name='zipcode')
email = models.EmailField(blank=True, null=True, verbose_name='email')
tel1 = models.CharField(max_length=15, blank=True, verbose_name='Tel. 1', null=True)
tel2 = models.CharField(max_length=15, blank=True, verbose_name='Tel. 2', null=True)
ssn = models.CharField(max_length=12, blank=True, db_index=True, null=True,verbose_name='SSN')
class Meta:
db_table = 'customer'
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
self.name = self.name.upper()
self.addr = self.addr.upper()
self.city = self.city.upper()
self.state = self.state.upper()
return super(Customer, self).save(*args, **kwargs)
在视图中,定义客户为后
customer = current_vehicle.customer_set.all()
我尝试了以下方法:
if 'customer' in request.POST:
if customer:
customer_form = CustomerForm(request.POST, instance=customer[0])
if customer_form.is_valid():
customer_form.save()
还尝试在定义 customer_form 之前添加:
customer.vehicle_id = current_vehicle.id
然后在表格之后:
customer_form.vehicle_id = current_vehicle.id
表单无效,因此未保存。在检查 form.errors 时,它总是报告vehicle_id 是必需的。
最后,在this 的答案之后,我通过添加:
obj = customer_form.save(commit=False)
并希望分配vehicle_id,但立即失败。
我错过了什么?
谢谢。
第一次编辑: 视图上的部分现在如下所示:
customer_form = CustomerForm(request.POST, instance=customer[0])
customer_form.save()
customer_form.vehicle_id.add(current_vehicle)
【问题讨论】:
一辆车可以关联多个客户吗?如果不是,那么我认为您的模型不正确,您应该在车辆模型上有一个客户外键,并且根本没有定义 M2M 字段。请显示两个模型定义并显示您的完整视图。 你使用的是哪个版本的 Django? 原始源代码中保存方法的最后一行是否正确缩进? Django 1.6.1。我在布局上犯了一个错误。现在它已修复并作为 save 方法的一部分正确显示返回。是的,在原始源代码中是正确的;只是这里错了。 【参考方案1】:您误解了这里的 ManyToMany 字段:
customer_form.vehicle_id = current_vehicle.id
vehicle_id
在您的 Customer 模型中定义为 ManyToMany 字段,因此您不能只为其分配一个 id。您必须添加VehicleSale
模型的实例,例如:
customer_form.vehicle_id.add(current_vehicle)
在此处查看文档:https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/
另请参阅此答案,了解为什么在填充 vehicle_id
关系之前无法保存:https://***.com/a/2529875/202168
【讨论】:
好的,严格遵循您提供的 django 文档链接,在执行 customer_form = CustomerForm(request.POST, instance=customer[0]) 之后,添加了 customer_form.save(),然后是 customer_form.vehicle_id。添加(当前_车辆)。不幸的是,在 customer_form.save() 行中失败,出现值错误(“无法更改客户,因为数据未验证”)。但是,request.POST 确实有我所做的更改,它只是在其中一个字段的末尾添加了一个字母。顺便说一句,这仍然有足够的空间容纳额外的字符。我做错了什么? 请显示您的Customer
模型的完整源代码。当您在模型表单上调用 save()
时,它会在模型上调用 full_clean
,因此模型验证中的某些内容失败了
添加了完整的客户模型。谢谢。
尝试将blank=True
添加到您的vehicle_id
字段
添加blank=True并执行customer_form.save()时,会删除中间表上的记录。重新创建后,如果我有 customer_form.save(commit=False) 然后添加车辆实例,则此行失败。还有其他建议吗?以上是关于更新 Django 中现有的 M2M 关系的主要内容,如果未能解决你的问题,请参考以下文章
Django Rest Framework更新嵌套的m2m对象。有谁知道更好的方法?
如何根据 M2M 关系在 django 模型中自动填充 IntegerField?