Django - OneToOneField 不起作用 - RelatedObjectDoesNotExist:用户没有用户详细信息
Django - OneToOneField does not work - RelatedObjectDoesNotExist: User has no userdetail
我正在尝试用这个扩展用户模型:
class UserDetail(models.Model):
user = models.OneToOneField(to=User, on_delete=models.CASCADE, verbose_name="Používateľ")
def __str__(self):
return f"{self.user.first_name} {self.user.last_name} ({self.user.username}) / Celková hodnota všetkých objednávok používateľa: {self.total_value_of_users_orders} €"
@property
def total_value_of_users_orders(self):
all_orders = Order.objects.all().filter(user=self.user, status__in=["NW", "WP", "PD", "IP", "ST", "DN"])
total_value = 0
for order in all_orders:
total_value += order.total_value
return total_value
但是,当我尝试访问 total_value_of_users_orders
属性 时,它不起作用:
from django.contrib.auth import get_user_model
User = get_user_model()
all_users = User.objects.all()
for u in all_users:
u.userdetail.total_value_of_users_orders
它显示了这个异常:
RelatedObjectDoesNotExist: User has no userdetail.
我做错了什么?我希望所有用户都拥有 total_value_of_users_orders
属性 returns 0(如果没有属于给定用户的订单)或确切的值(如果有属于给定用户的订单)用户)。
谢谢
您需要先检查是否存在:
if hasattr(u, 'userdetail'):
print(u.userdetail.total_value_of_users_orders)
请注意,以下内容仍然会给您一个 RelatedObjectDoesNotExist
错误:
if u.userdetail:
print(u.userdetail.total_value_of_users_orders)
在创建User的时候使用django signal来创建UserDetail这样每个用户都会有自己的UserDetail并且查询可以访问total_value_of_users_order
from django.db.models.signals import post_save
# ... your models
def create_user_detail(sender, created, instance, **kwargs):
if created:
UserDetail.objects.create(user=instance)
# ...
post_save.connect(create_user_detail, sender=User)
这意味着您的用户在数据库中没有 userdetail
相关的 one-to-one 对象。您可以在需要时创建它,也可以在创建用户时创建它。
有几种处理方式:
- 创建用户后立即创建 UserDetail 对象。这可以使用 django signals 轻松完成。 (您可能需要修改生成的迁移来为旧迁移创建 UserDetail。)
- 在您想要访问时创建 UserDetail 对象(如果不存在)。您可以自己实现或使用 django-annoying 的 AutoOneToOneField。
- 每次要访问时检查用户是否有
userdetail
(使用 hasattr
)。阅读 the documentation。 (有效,但我不推荐)
如果您可以扩展 User 模型,还有其他选项可能会工作得更好,但您似乎已经迁移了它,所以不会那么容易。
我正在尝试用这个扩展用户模型:
class UserDetail(models.Model):
user = models.OneToOneField(to=User, on_delete=models.CASCADE, verbose_name="Používateľ")
def __str__(self):
return f"{self.user.first_name} {self.user.last_name} ({self.user.username}) / Celková hodnota všetkých objednávok používateľa: {self.total_value_of_users_orders} €"
@property
def total_value_of_users_orders(self):
all_orders = Order.objects.all().filter(user=self.user, status__in=["NW", "WP", "PD", "IP", "ST", "DN"])
total_value = 0
for order in all_orders:
total_value += order.total_value
return total_value
但是,当我尝试访问 total_value_of_users_orders
属性 时,它不起作用:
from django.contrib.auth import get_user_model
User = get_user_model()
all_users = User.objects.all()
for u in all_users:
u.userdetail.total_value_of_users_orders
它显示了这个异常:
RelatedObjectDoesNotExist: User has no userdetail.
我做错了什么?我希望所有用户都拥有 total_value_of_users_orders
属性 returns 0(如果没有属于给定用户的订单)或确切的值(如果有属于给定用户的订单)用户)。
谢谢
您需要先检查是否存在:
if hasattr(u, 'userdetail'):
print(u.userdetail.total_value_of_users_orders)
请注意,以下内容仍然会给您一个 RelatedObjectDoesNotExist
错误:
if u.userdetail:
print(u.userdetail.total_value_of_users_orders)
在创建User的时候使用django signal来创建UserDetail这样每个用户都会有自己的UserDetail并且查询可以访问total_value_of_users_order
from django.db.models.signals import post_save
# ... your models
def create_user_detail(sender, created, instance, **kwargs):
if created:
UserDetail.objects.create(user=instance)
# ...
post_save.connect(create_user_detail, sender=User)
这意味着您的用户在数据库中没有 userdetail
相关的 one-to-one 对象。您可以在需要时创建它,也可以在创建用户时创建它。
有几种处理方式:
- 创建用户后立即创建 UserDetail 对象。这可以使用 django signals 轻松完成。 (您可能需要修改生成的迁移来为旧迁移创建 UserDetail。)
- 在您想要访问时创建 UserDetail 对象(如果不存在)。您可以自己实现或使用 django-annoying 的 AutoOneToOneField。
- 每次要访问时检查用户是否有
userdetail
(使用hasattr
)。阅读 the documentation。 (有效,但我不推荐)
如果您可以扩展 User 模型,还有其他选项可能会工作得更好,但您似乎已经迁移了它,所以不会那么容易。