繁体   English   中英

django.db.utils.ProgrammingError:关系“...”不存在

[英]django.db.utils.ProgrammingError: relation “…” does not exist

我希望 Django 中的用户对象链接到客户端 object(我创建)。 为此,我通过一对一链接扩展用户 model 与链接用户和客户端的配置文件 class(我创建)class 配置文件。 我按照https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html的说明进行操作。

但是,当我创建用户 object 时,默认情况下我无权访问我想要我的用户对象

我的模型.py:

from django.contrib.auth.models import User

[...]

class Client(models.Model):
    name = models.CharField(max_length=255)
    address = models.CharField(max_length=255)
    [...]

class Profile(models.Model):
    need_setup = Client.objects.get(name='NEED TO ADD CLIENT IN ADMIN > PROFILES')
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    client = models.ForeignKey(Client, on_delete=models.DO_NOTHING)

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

当我进行迁移/运行服务器时出现问题(我的应用程序称为“仪表板”): django.db.utils.ProgrammingError: relation "dashboard_client" does not exist LINE 1: ...nque_id", "dashboard_client"."date_creation" FROM "dashboard...因为need_setup = Client.objects.get(name='NEED TO ADD CLIENT IN ADMIN > PROFILES') (如果我将其注释掉就没有问题)。

我可以通过在数据库中手动创建一个名为“NEED TO ADD CLIENT IN ADMIN > PROFILES”的客户端来解决这个问题,然后运行我的迁移和部署,但我正在寻找一种更好的方法来解决这个问题,尤其是当我从在产品中划伤。

我试图覆盖 app.py 中的def ready(self) function,这是一个在应用程序启动时运行的 function。 不幸的是,它在运行之前需要有正确的 models.py。

感谢您的想法和想法!

根据我对您的情况的理解,您希望:

  1. 在创建用户后触发创建配置文件 object 并将配置文件 object 链接到用户(已使用您的保存后信号完成)。
  2. 判断profile object是否需要配置client (要解决的问题)

在这种情况下,您将need_setup字段设置为 BooleanField ,其属性为default=True 这意味着默认情况下需要设置新创建的任何 Profile 对象。 为了安全起见,您可以添加属性editable=False ,这样该字段就不能被外部修改。

class Profile(models.Model):
    need_setup = models.BooleanField(default=True, editable=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    client = models.ForeignKey(Client, on_delete=models.DO_NOTHING)

接下来,您覆盖模型的save方法以根据是否填充client来切换 boolean 字段。

class Profile(models.Model):
    need_setup = models.BooleanField(default=True, editable=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    client = models.ForeignKey(Client, on_delete=models.DO_NOTHING)

    def save(self, *args, **kwargs):
        if self.client is None:
            self.need_setup = True
        else:
            self.need_setup = False

        super().save(*args, **kwargs)

另一种解决方案是使用 python 的@property 使用此解决方案,您基本上将need_setup设置为属性而不是字段。 这具有不必在数据库级别创建字段的优点。 此解决方案的缺点是您不能在 django 查询集中使用它,例如Profile.objects.filter(need_setup=True) ,因为 django 查询集使用数据库字段。

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    client = models.ForeignKey(Client, on_delete=models.DO_NOTHING)

    @property
    def need_setup(self):
        return not bool(self.client)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM