8

I have:

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

On some croned daily request I do:

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

Can it be done on DB server with update?

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

Ok, I can't update, thanks. But only thing I need is to TRUNCATE m2m internal table, is it possible to perform from django? How to know it's name whithout mysql's console "SHOW TABLES"?

Ivan Borshchov
  • 3,036
  • 5
  • 40
  • 62

2 Answers2

9

If you want to update the m2m fields only and do not want to delete the m2m objects you can use the following:

#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)

for 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)
sgauri
  • 694
  • 8
  • 18
6

Query-1:

No, you cannot use .update() method to update a ManyToManyField.

Django's .update() method does not support ManyToManyField.

As per the docs from the section on 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.

Query-2:

If you want to delete all the objects of m2m table, you can use .delete() queryset method.

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

Another method is to execute the raw SQL directly. This method is faster than the previous one.

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

Query-3:

To get the table name of a model, you can use db_table model Meta option.

my_model_object._meta.db_table # gives the db table name
Rahul Gupta
  • 46,769
  • 10
  • 112
  • 126
  • Yes, but I have no m2m MyModel class as you see, I have only today_ref_viewed_ips = ManyToManyField, has it also some meta information? – Ivan Borshchov Sep 13 '15 at 20:10
  • 1
    `UniqAddress` is the model of `today_ref_viewed_ips`. To get its table name, you can use `uniq_address_object._meta.db_table`. Using `.delete()` on this model will delete all the objects in the `UniqAddress` table. Think twice if you want to do `UniqAddress.objects.delete()` as all the objects of this model will be deleted. – Rahul Gupta Sep 14 '15 at 02:46