我想编写一个函数,当执行
"GET"
请求时,会将以下字段更改为:"inaction"
和 "lastAction"
到 2
和 datetime.now()
。但是当我第一次编写代码时,遇到了错误:TypeError: cannot unpack non-iterable int object
。
此代码:
def update(self, res_id: str):
user, updated = User.objects.filter(id=res_id).update(inaction="2", lastAction=datetime.now())
code_status = HTTPStatus.ACCEPTED if updated else HTTPStatus.OK.value
return user, code_status
因此,我将代码重写为以下内容并开始工作:
def update(self, res_id: str):
updated_rows = User.objects.filter(id=res_id).update(inaction="2", lastAction=datetime.now())
user = User.objects.filter(id=res_id).first()
code_status = HTTPStatus.ACCEPTED if updated_rows else HTTPStatus.OK.value
return user, code_status
但是在这段代码中,我担心以下形式的重复:
User.objects.filter(id=res_id)
。我怎样才能避免它们?
models.py:
class User(models.Model):
operatorId = models.CharField(max_length=64, null=False)
createdAt = models.DateTimeField(auto_now_add=True, null=True)
operator = models.CharField(max_length=10, null=True)
inaction = models.IntegerField(default=1)
lastAction = models.DateTimeField(null=True)
class Meta:
verbose_name = 'user'
verbose_name_plural = 'users'
db_table = "users"
ordering = ('-createdAt',)
def __str__(self) -> str:
return UsersEntity.to_string(self)
实体.py
class UsersEntity:
id: int
operatorId: str = None
createdAt: date = None
operator: str = None
inaction: int = 1
@staticmethod
def to_string(user: 'UsersEntity') -> str:
operatorId = f"({user.operatorId}):" if user.operatorId else ValueError
return f'{user.id} -> {operatorId}'
要优化 Django 代码并避免重复
User.objects.filter(id=res_id)
查询,您应该有效地利用 Django 的查询集和事务。
你可以这样做:
from django.db import transaction
from django.utils import timezone
def update(self, res_id: str):
with transaction.atomic():
# Lock the rows for update and get the user instance
user = User.objects.select_for_update().filter(id=res_id).first()
# Check if the user exists
if not user:
code_status = HTTPStatus.NOT_FOUND.value
return None, code_status
# Update the fields
user.inaction = 2
user.lastAction = timezone.now()
user.save(update_fields=['inaction', 'lastAction'])
code_status = HTTPStatus.ACCEPTED.value
return user, code_status
通过在此 Django 代码中使用
transaction.atomic()
,我确保所有数据库更改都粘在一起。这是一种全有或全无的方法。我还使用 select_for_update()
锁定正在处理的行,以避免两个更新同时发生时出现任何混淆。在更新之前,我检查用户是否确实存在以避免不必要的步骤。一旦找到用户,我就当场更新他们的“inaction”和“lastAction”,这更简单。另外,我使用 django.utils.timezone.now()
来正确处理时间。最后,我使用适当的代码返回用户信息,例如如果用户不存在,则显示“未找到用户”。