【发布时间】:2021-01-20 04:07:30
【问题描述】:
我有一个自定义用户配置文件模型。该模型具有can_edit 属性,该属性使用ContentType 和Permission 对象来确定用户是否具有权限。我在序列化程序中使用此属性,它工作正常,但效率极低,因为每个用户都会再次查询 ContentType 和 Permission。
似乎prefetch_related 可以放在这里,但我不知道如何应用它,因为这些对象不是通过某些属性直接引用的,而是单独查询的。是否可以事先获取ContentType 和Permission 并在进一步查询中使用结果?
这是我的模型:
class CustomProfile(models.Model):
user = models.OneToOneField(User, related_name="profile", on_delete=models.CASCADE)
@property
def can_edit(self):
content_type = ContentType.objects.get_for_model(Article)
permission, _ = Permission.objects.get_or_create(
codename="edit", name="Can edit", content_type=content_type
)
return self.user.has_perm(self._permission_name(permission))
def _permission_name(self, permission):
return f"{permission.content_type.app_label}.{permission.codename}"
我当前的查询:
User.objects.order_by("username").select_related("profile")
我的序列化器:
class UserSerializer(serializers.ModelSerializer):
can_edit = serializers.ReadOnlyField(source="profile.can_edit")
class Meta:
model = User
fields = (
"id",
"username",
"first_name",
"last_name",
"is_active",
"is_staff",
"can_edit",
)
事实上,我有不止一个与can_edit 内容相似的属性,因此每个用户实例添加了大约6 个对ContentType 和Permission 的不必要查询。
如何优化它?
【问题讨论】:
-
不确定这是否是您想要的,但请查看 cached_property docs.djangoproject.com/en/3.1/ref/utils/…
-
不,有多个对象,每个对象都会调用自己的属性,可能具有不同的值,并且它们都在下面重复相同的查询
-
",我有不止一个属性与
can_edit" 在这个UserSerializer类或其他类中? @Djent -
@ArakkalAbu - 同班
-
@Djent 你能添加一个例子吗? (也许我可以提供一个准确的解决方案)
标签: python django django-rest-framework django-orm