Django模型保存时如何为多对多关系的owner字段添加当前用户?
解决Django中为对象添加多对多所有者的问题
嘿,我完全懂你的困扰!当把owner改成ManyToManyField之后,直接像外键那样赋值obj.owner = request.user肯定行不通——因为多对多字段对应的是一个关系管理器,不是单个对象,得用专门的方法来添加关联。
首先先纠正你代码里的一个小拼写错误:ManytoManyField要写成ManyToManyField(注意中间的T是大写),不然Django会识别不了这个字段类型。修改后的models.py应该是:
class Article(models.Model): # 你的其他字段... owner = models.ManyToManyField(User, blank=True) # 你的其他字段...
接下来是admin.py里的关键修改。因为多对多关系需要对象先被保存到数据库(拥有主键ID)才能建立关联,所以我们得先保存对象,再添加当前用户作为所有者。这里给你两种场景的写法:
场景1:仅在创建新文章时添加当前用户作为所有者
如果你希望只有在第一次创建文章时自动添加当前用户,后续修改文章时不重复添加(避免同一个用户被多次加入所有者列表),可以这样写:
class ArticleAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): # 先调用父类方法保存对象,确保对象有主键 super().save_model(request, obj, form, change) # 如果是新建对象(change为False表示第一次创建),且当前用户还没在所有者里 if not change and request.user not in obj.owner.all(): obj.owner.add(request.user)
场景2:每次保存都确保当前用户在所有者列表中
如果你希望不管是创建还是修改文章,当前用户都始终在所有者列表里(比如防止误删),可以去掉not change的判断:
class ArticleAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): super().save_model(request, obj, form, change) if request.user not in obj.owner.all(): obj.owner.add(request.user)
为什么不能直接赋值?
ForeignKey对应的是单个对象,所以可以直接赋值;但ManyToManyField对应的是一个用户集合,Django给它提供了add()、remove()、clear()这些方法来管理关联关系,直接赋值会触发错误,因为它不是单个对象类型。
这样修改后,你创建文章时当前用户会自动被加入所有者列表,后续也能通过admin界面添加其他用户作为所有者啦!
内容的提问来源于stack exchange,提问作者user11036089
相关产品推荐
相关产品推荐

