如何使用 on_delete 属性在用户模型的外键字段中设置用户全名?

Posted

技术标签:

【中文标题】如何使用 on_delete 属性在用户模型的外键字段中设置用户全名?【英文标题】:How can I set user full name in foreignkey field with User Model using on_delete attribute? 【发布时间】:2017-07-26 17:26:14 【问题描述】:

我在 django 中有一个模型,它有外键和用户模型。

class News(models.Model):
    user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.SET(???))
    message - models.TextField()

因此,当任何用户帐户从数据库中删除时,新闻表中的条目也会根据用户删除。所以我希望当删除任何用户帐户时,我需要使用'on_delete=models.SET(???)'在用户字段中设置他/她的全名

例子:

如果我有 first_name = 'Neeraj' 和 last_name='Kumar' 的用户 当我想删除该用户帐户时,我想在 News 表中保存他的名字。

【问题讨论】:

【参考方案1】:

News 模型中的user 字段映射到User 模型实例。

您不能将字符串分配给该字段。您只能为 null 分配一个 User 模型实例。

您必须提供替代用户来代替已删除的用户。因此,要么保留一个用户进行替换,要么在删除时创建一个。 docs里解释的很清楚。

您可以做的一件事是向News 模型添加一个新的name 字段,并在创建News 实例时填充它。

class News(models.Mode):
    user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.SET_NULL)
    name = models.CharField()

    def save(self, *args, **kwargs):
        if not self.id:
            self.name = self.user.first_name + self.user.last_name
        super(News, self).save(*args, **kwargs)

现在当User 被删除时,user 字段设置为 NULL,name 字段包含所需的名称信息。

【讨论】:

虽然这是一个很好的解决方案,但就目前而言,外键没有任何作用。是的,存在反向关系,但无论如何您都必须实现“按作者姓名查找帖子”,并为已删除的作者不再可能的事情添加额外的逻辑。最好的解决方案是不允许删除用户,而是将其标记为非活动状态。这就是为什么在用户模型上有is_active【参考方案2】:

与上一个答案一样,您不能将字符串值分配给 ForeignKey 字段。使用这种 on_delete 方法,您可以在这种情况下为特殊用户分配类似于已删除的内容。此外,如果您真的想将用户名分配给另一个字段,您可以使用 Django 信号来完成。 on_delete 无能为力。

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models

def get_sentinel_user():
    return get_user_model().objects.get_or_create(username='deleted')[0]

class MyModel(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET(get_sentinel_user),
    )

【讨论】:

以上是关于如何使用 on_delete 属性在用户模型的外键字段中设置用户全名?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Django中的外键关系中的任何/ exists / all逻辑检索查询集?

如何使用 Devise gem 生成的 User 模型生成的 UserID 作为其他模型的外键?

如何使用 Graphene-Django Relay 中的外键关系更新模型?

DJango 和 Python 的外键设置问题

Django的外键创建

如何从循环中的外键关系中获取所有值?