如何更新 Django 中的 m2m 字段

How to .update m2m field in django

我有:

class MyUser(Model):
    today_ref_viewed_ips = ManyToManyField(
        UniqAddress, 
        related_name='today_viewed_users', 
        verbose_name="Adresses visited referal link today")
    ...

在一些 croned 日常请求中,我做了:

for u in MyUser.objects.all():
    u.today_ref_viewed_ips.clear()

可以在数据库服务器上更新吗?

MyUser.objects.all().update(...)

好的,我无法更新,谢谢。但我唯一需要的是截断 m2m 内部 table,是否可以从 django 执行?如何在没有 mysql 的控制台 "SHOW TABLES" 的情况下知道它的名字?

查询-1:

不,你不能使用.update() method to update a ManyToManyField

Django 的 .update() 方法不支持 ManyToManyField。

根据 updating multiple objects at once:

部分的文档

You can only set non-relation fields and ForeignKey fields using this method. To update a non-relation field, provide the new value as a constant. To update ForeignKey fields, set the new value to be the new model instance you want to point to.

查询 2:

如果想删除m2m的所有对象table,可以使用.delete()queryset方法

MyModel.objects.all().delete() # deletes all the objects

另一种方法是直接执行raw SQL。这种方法比上一种方法快

from django.db import connection
cursor = connection.cursor()
cursor.execute("TRUNCATE TABLE table_name")

查询-3:

要获取模型的 table 名称,您可以使用 db_table 模型 Meta 选项。

my_model_object._meta.db_table # gives the db table name

如果您只想更新 m2m 字段而不想删除 m2m 对象,您可以使用以下方法:

#if you have **list of pk** for new m2m objects

today_ref_pk = [1,2,3]
u = MyUser.objects.get(pk=1)
u.today_ref_viewed_ips.clear()
u.today_ref_viewed_ips.add(*today_ref_pk)

对于 django >=1.11 documentation:

# if you have the **list of objects** for new m2m and you dont have the 
# issue of race condition, you can do the following:

today_ref_objs = [obj1, obj2, obj3]
u = MyUser.objects.get(pk=1)
u.today_ref_viewed_ips.set(today_ref_objs, clear=True)