Introduction to various usages of Django model update

created at 07-17-2021 views: 4

Model update general usage

If our table structure is like this

class User(models.Model):
    username = models.CharField(max_length=255, unique=True, verbose_name='username')
    is_active = models.BooleanField(default=False, verbose_name='status')

Then we can use the following two methods to modify the user name and status:

method 1

User.objects.filter(id=1).update(username='nick',is_active=True)

method 2

_t = User.objects.get(id=1)
_t.username='nick'
_t.is_active=True
_t.save()
  • Method 1 is suitable for updating a batch of data, similar to the mysql statement update user set username='nick' where id = 1
  • Method 2 is suitable for updating one piece of data, and only one piece of data can be updated. This method is recommended when only one piece of data is updated. In addition, this method has another advantage. Let’s look down.

Update of fields with auto_now attribute

We usually add three default fields to the table

Self-incrementing ID, this django has been added by default, just like the table creation statement above, although only the username and is_active fields are written, there will be a default self-incrementing id field after the table is built.

Creation time, used to identify the creation time of this record, has the auto_now_add attribute, and the current time will be automatically filled into this field when the record is created

Modification time, used to identify the last modification time of this record, with auto_now attribute, fill the current time to this field when the record changes

Table structure like below

class User(models.Model):
     create_time = models.DateTimeField(auto_now_add=True, verbose_name='Create Time')
     update_time = models.DateTimeField(auto_now=True, verbose_name='Update time')
     username = models.CharField(max_length=255, unique=True, verbose_name='username')
     is_active = models.BooleanField(default=False, verbose_name='active state')

When the table has a field with auto_now attribute and you want it to be updated automatically, you must use the update method 2 above, otherwise the auto_now field will not be updated, that is:

_t = User.objects.get(id=1)
_t.username='nick'
_t.is_active=True
_t.save()

json/dict type data update field

At present, the mainstream web opening methods pay attention to the separation of front and back ends. After the separation, the data format of the front and back end interactions mostly use the general jason type. So how to update the json format data to the database conveniently with the least code? The following two methods can also be used:

method 1

data = {'username':'nick','is_active':'0'}
User.objects.filter(id=1).update(**data)

The same method cannot automatically update the value of the field with the auto_now attribute

Usually we add an asterisk (*) before the variable to indicate that the variable is a tuple/list, and add two asterisks to indicate that the parameter is a dictionary

Method 2

data = {'username':'nick','is_active':'0'}
_t = User.objects.get(id=1)
_t.__dict__.update(**data)
_t.save()

Method two and method one also cannot automatically update the value of the auto_now field

Note that a dict method is used here

Methid 3

_t = User.objects.get(id=1)
_t.role=Role.objects.get(id=3)
_t.save()

ForeignKey field update

If there is a Foreignkey foreign key in our table, how to update it?

class User(models.Model):
     create_time = models.DateTimeField(auto_now_add=True, verbose_name='Create Time')
     update_time = models.DateTimeField(auto_now=True, verbose_name='Update time')
     username = models.CharField(max_length=255, unique=True, verbose_name='username')
     is_active = models.BooleanField(default=False, verbose_name='active state')
     role = models.ForeignKey(Role, on_delete=models.CASCADE, null=True, verbose_name='Role')

method 1

User.objects.filter(id=1).update(role=2)

The easiest way is to directly set the role field to an id

Of course, you can also use dict as a parameter to update:

User.objects.filter(id=1).update(**{'username':'nick','role':3})

Method 2

_role = Role.objects.get(id=2)
User.objects.filter(id=1).update(role=_role)

You can also assign an instance to the role

Of course, you can also use dict as a parameter to update:

_role = Role.objects.get(id=1)
User.objects.filter(id=1).update(**{'username':'nick','role':_role})

Method 3

_t = User.objects.get(id=1)
_t.role=Role.objects.get(id=3)
_t.save()

Note: The role here must be assigned to an object, and the id cannot be written, otherwise it will report an error "User.role" must be a "Role" instance

When using dict as a parameter update, there is a little difference, the following code:

_t = User.objects.get(id=1)
_t.__dict__.update(**{'username':'nick','role_id':2})
_t.save()

Foreignkey foreign key must be added with _id, for example: {'role_id':3}

Role_id must be followed by an id (either int or str type), not a role instance

ManyToManyField field update

What is the impact of updating if there is ManyToManyField in our table?

class User(models.Model):
     create_time = models.DateTimeField(auto_now_add=True, verbose_name='Create Time')
     update_time = models.DateTimeField(auto_now=True, verbose_name='Update time')
     username = models.CharField(max_length=255, unique=True, verbose_name='username')
     is_active = models.BooleanField(default=False, verbose_name='active state')
     role = models.ForeignKey(Role, on_delete=models.CASCADE, null=True, verbose_name='Role')
     groups = models.ManyToManyField(Group, null=True, verbose_name='Group')

m2m update: There is no direct update method for the m2m field, it can only be updated by clearing it and adding it.

_t = User.objects.get(id=1)
_t.groups.clear()
_t.groups.add(*[1,3,5])
_t.save()

add(): Add a value to the m2m field, and the list can be used when there are multiple values, refer to the example above

_t.groups.add(2)

_t.groups.add(Group.objects.get(id=2))

remove(): The m2m field removes a value, and the list can be used when there are multiple values, refer to the example above

_t.groups.remove(2)

_t.groups.remove(Group.objects.get(id=2))

clear(): Clear the value of the m2m field

Please log in to leave a comment.