bry*_*ryn 7 django idioms django-models
我有一个名为StaffSettings的Django模型,它包含我的Django应用程序中用户的各种配置选项.每个用户在StaffSettings表中最多只有一个条目.
假设一个设置是default_year_level,我有我的用户对象的代码,如:
def set_default_year_level(u, year_level):
obj, _created = StaffSettings.objects.get_or_create(user=u)
obj.default_year_level = year_level
obj.save()
Run Code Online (Sandbox Code Playgroud)
我希望函数的主体适合一行,因为它看起来像一个常见的用例,但如果我将其定义为
def set_default_year_level(u, year_level):
StaffSettings.objects.filter(user=u).update(default_year_level=year_level)
Run Code Online (Sandbox Code Playgroud)
如果有问题的用户已在StaffSettings表中有一行,但如果它不存在则不会创建相关行,这可以正常工作.
编写此代码的惯用/最佳方法是什么?(例如,是否存在某种filter_or_create功能?还是其他人编写装饰器/辅助函数来处理这个习惯用法?)
从 Django 1.7 开始,您可以使用update_or_create():
def set_default_year_level(u, year_level):
obj, _created = StaffSettings.objects.update_or_create(
user=u,
default_year_level=year_level
)
Run Code Online (Sandbox Code Playgroud)
或者,对于上一个答案中解释的更通用的情况:
def set_default_values(u, **kwargs):
obj, _created = StaffSettings.objects.update_or_create(user=u, defaults=kwargs)
Run Code Online (Sandbox Code Playgroud)
这也满足您的额外要求
我希望函数体适合一行
我没有看到你的第一个函数有任何问题,我会为这个用例写同样的东西.
但是,如果您需要在模型的许多字段上使用相同的功能,并且您不想重复自己,则可以将该字段作为参数传递:
def set_default_value(u, field, value):
obj, _created = StaffSettings.objects.get_or_create(user=u)
setattr(obj, field, value)
obj.save()
Run Code Online (Sandbox Code Playgroud)
而且我会远离update()函数,因为这个函数意味着一次更新多个对象并且不会触发你的模型上的save()方法和信号(参见https://docs.djangoproject.com/en/dev/topics/db/queries/#newed-multiple-objects-at-once)
| 归档时间: |
|
| 查看次数: |
3135 次 |
| 最近记录: |