【问题标题】:How to .update m2m field in django如何在 django 中更新 m2m 字段
【发布时间】:2022-01-16 15:56:50
【问题描述】:

我有:

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 内部表,是否可以从 django 执行?没有 mysql 的控制台“SHOW TABLES”如何知道它的名字?

【问题讨论】:

    标签: sql django many-to-many


    【解决方案1】:

    如果您只想更新 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)
    

    【讨论】:

      【解决方案2】:

      查询 1:

      不,您不能使用.update() 方法更新ManyToManyField

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

      根据updating multiple objects at once: 部分的文档

      您只能使用此设置非关系字段和ForeignKey 字段 方法。 要更新非关系字段,请将新值作为 持续的。要更新 ForeignKey 字段,请将新值设置为新的 您要指向的模型实例。

      查询 2:

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

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

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

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

      查询 3:

      要获取模型的表名,可以使用db_table model Meta 选项。

      my_model_object._meta.db_table # gives the db table name
      

      【讨论】:

      • 是的,但是我没有你看到的 m2m MyModel 类,我只有 today_ref_viewed_ips = ManyToManyField,还有一些元信息吗?
      • UniqAddresstoday_ref_viewed_ips 的模型。要获取其表名,您可以使用uniq_address_object._meta.db_table。在此模型上使用.delete() 将删除UniqAddress 表中的所有对象。如果你想做UniqAddress.objects.delete(),请三思,因为这个模型的所有对象都将被删除。
      猜你喜欢
      • 1970-01-01
      • 2016-03-12
      • 1970-01-01
      • 2021-08-22
      • 2020-08-13
      • 2020-11-22
      • 2013-02-05
      • 2023-01-27
      • 2018-07-28
      相关资源
      最近更新 更多