我想知道我是否可以实例化数据库记录的id
的空假模型。我找到了创建模型的方法,但我想要一个生产友好的解决方案。
问题解释:
我想列出选择在公共模式下显示的用户的用户设置:
user_displayed_list = UserPublicProfile.objects.filter(
displayed = True,
).only(
'user_id',
'is_premium',
)
user_settings_list = []
for user_displayed in user_displayed_list:
# I have to send user Instance to the next method :
user_settings = self.get_user_settings(user_displayed.user)
user_settings_list.append(user_settings)
# But ’user_displayed.user’ run an new SQL query
我知道我可以改进我的查询集:
user_displayed_list = UserPublicProfile.objects.filter(
displayed = True,
).select_related(
'user'
).only(
'user',
'is_premium',
)
但是它使一个无用的连接,因为我只需要get_user_settings()
中的用户id
字段:
get_user_settings()
方法(它可以帮助理解上下文):
def get_user_settings(self, user)
user_settings = UserSettings.objects.get(user = user)
return user_settings
在实际工程中,该方法运行了更多的业务特性
是否有一种方法来实例化一个只有id
字段填充的用户模型实例?
我不想为此目的使用自定义空类。我想要一个object User.
我没有找到任何东西。如果可能的话,我可以这样使用它:
for user_displayed in user_displayed_list:
FakeUser = User.objects.create_fake(id = user_displayed.user_id)
# I have to send user Instance to the next method :
user_settings = self.get_user_settings(FakeUser)
在没有看到完整模型的情况下,我做了一些假设。假设UserSettings
对User
有一个外键。UserPublicProfile
也一样。或者User
有UserSettings
的外键。
假设,我看到两个解决方案。
<标题>解决方案# 1;充分利用ORM刚刚看到你关于"遗留方法,使用了很多次"的评论。
Django的关系是非常聪明的。它们接受ForeignKey的对象或ID。您可能会认为这只适用于User
。但是如果你通过了id
, Django ORM会帮助你。
def get_user_settings(self, user)
user_settings = UserSettings.objects.get(user = user)
return user_settings
实际上,它们的作用是一样的:
UserSettings.objects.get(user=1)
UserSettings.objects.get(user_id=1)
这意味着这应该工作,而不需要额外的查询:
user_displayed_list = UserPublicProfile.objects.filter(
displayed = True,
).only(
'user_id',
'is_premium',
)
user_settings_list = []
for user_displayed in user_displayed_list:
# I have to send user Instance to the next method :
user_settings = self.get_user_settings(user_displayed.user_id) # pass the user_id instead of the object.
user_settings_list.append(user_settings)
解决方案#2:链式关系
另一个解决方案,再次,仍然假设相当多;)它会认为你可以把模型链在一起。假设这些FK存在:用户→UserSetting。你可以这样做:
user_displayed_list = UserPublicProfile.objects.filter(
displayed = True,
).select_related(
'user', 'user__usersettings', # depends on naming of relations
).only(
'user',
'is_premium',
)
for user_displayed in user_displayed_list:
# I have to send user Instance to the next method :
user_settings = user_displayed.user.usersettings # joined, so should cause no extra queries. Depends on naming of relations.
user_settings_list.append(user_settings)
标题>