gpt4 book ai didi

python - Django - 条件外键

转载 作者:太空狗 更新时间:2023-10-30 02:37:25 24 4
gpt4 key购买 nike

我的程序中有以下 4 个模型 - 用户、品牌、代理商和创作者。

用户是品牌、代理商和创作者的超集。

用户可以是品牌、代理机构或创作者。他们不能承担超过一种角色。它们的角色由 accountType 属性定义。如果它们未设置(即 0),则不存在正式连接。

如何在我的模型中表达这一点?

用户模型

class User(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
email = models.EmailField(max_length=255, null=True, default=None)
password = models.CharField(max_length=255, null=True, default=None)
ACCOUNT_CHOICE_UNSET = 0
ACCOUNT_CHOICE_BRAND = 1
ACCOUNT_CHOICE_CREATOR = 2
ACCOUNT_CHOICE_AGENCY = 3
ACCOUNT_CHOICES = (
(ACCOUNT_CHOICE_UNSET, 'Unset'),
(ACCOUNT_CHOICE_BRAND, 'Brand'),
(ACCOUNT_CHOICE_CREATOR, 'Creator'),
(ACCOUNT_CHOICE_AGENCY, 'Agency'),
)
account_id = models.ForeignKey(Brand)
account_type = models.IntegerField(choices=ACCOUNT_CHOICES, default=ACCOUNT_CHOICE_UNSET)

class Meta:
verbose_name_plural = "Users"

def __str__(self):
return "%s" % self.email

品牌型号

class Brand(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255, null=True, default=None)
brand = models.CharField(max_length=255, null=True, default=None)
email = models.EmailField(max_length=255, null=True, default=None)
phone = models.CharField(max_length=255, null=True, default=None)
website = models.CharField(max_length=255, null=True, default=None)

class Meta:
verbose_name_plural = "Brands"

def __str__(self):
return "%s" % self.brand

创作者模式

class Creator(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
first_name = models.CharField(max_length=255, null=True, default=None)
last_name = models.CharField(max_length=255, null=True, default=None)
email = models.EmailField(max_length=255, null=True, default=None)
youtube_channel_username = models.CharField(max_length=255, null=True, default=None)
youtube_channel_url = models.CharField(max_length=255, null=True, default=None)
youtube_channel_title = models.CharField(max_length=255, null=True, default=None)
youtube_channel_description = models.CharField(max_length=255, null=True, default=None)
photo = models.CharField(max_length=255, null=True, default=None)
youtube_channel_start_date = models.CharField(max_length=255, null=True, default=None)
keywords = models.CharField(max_length=255, null=True, default=None)
no_of_subscribers = models.IntegerField(default=0)
no_of_videos = models.IntegerField(default=0)
no_of_views = models.IntegerField(default=0)
no_of_likes = models.IntegerField(default=0)
no_of_dislikes = models.IntegerField(default=0)
location = models.CharField(max_length=255, null=True, default=None)
avg_views = models.IntegerField(default=0)
GENDER_CHOICE_UNSET = 0
GENDER_CHOICE_MALE = 1
GENDER_CHOICE_FEMALE = 2
GENDER_CHOICES = (
(GENDER_CHOICE_UNSET, 'Unset'),
(GENDER_CHOICE_MALE, 'Male'),
(GENDER_CHOICE_FEMALE, 'Female'),
)
gender = models.IntegerField(choices=GENDER_CHOICES, default=GENDER_CHOICE_UNSET)

class Meta:
verbose_name_plural = "Creators"

def __str__(self):
return "%s %s" % (self.first_name,self.last_name)

代理模型

class Agency(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255, null=True, default=None)
agency = models.CharField(max_length=255, null=True, default=None)
email = models.EmailField(max_length=255, null=True, default=None)
phone = models.CharField(max_length=255, null=True, default=None)
website = models.CharField(max_length=255, null=True, default=None)

class Meta:
verbose_name_plural = "Agencies"

def __str__(self):
return "%s" % self.agency

更新:

所以我在模型中将其缩减为这一点:

ACCOUNT_CHOICE_UNSET = 0
ACCOUNT_CHOICE_BRAND = 1
ACCOUNT_CHOICE_CREATOR = 2
ACCOUNT_CHOICE_AGENCY = 3
ACCOUNT_CHOICES = (
(ACCOUNT_CHOICE_UNSET, 'Unset'),
(ACCOUNT_CHOICE_BRAND, 'Brand'),
(ACCOUNT_CHOICE_CREATOR, 'Creator'),
(ACCOUNT_CHOICE_AGENCY, 'Agency'),
)
account_type = models.IntegerField(choices=ACCOUNT_CHOICES, default=ACCOUNT_CHOICE_UNSET)
limit = models.Q(app_label='api', model='Brand') | \
models.Q(app_label='api', model='Creator') | \
models.Q(app_label='api', model='Agency')
content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_type_choices(), related_name='user_content_type')
content_object = GenericForeignKey('content_type', 'email')
  • 如果 account_type = 1 则链接到品牌模型
  • 如果 account_type = 2 则链接到创建者模型
  • 如果 account_type = 3 则链接到代理模型

我该如何实现?收到此错误:

  File "/Users/projects/adsoma-api/api/models.py", line 7, in <module>
class User(models.Model):
File "/Users/projects/adsoma-api/api/models.py", line 28, in User
content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_type_choices(), related_name='user_content_type')
NameError: name 'get_content_type_choices' is not defined

最佳答案

您是否尝试过探索 Django 的 GenericForeignKey 字段?

class User(models.Model):
...
limit = models.Q(app_label='your_app_label', model='brand') |
models.Q(app_label='your_app_label', model='creator') |
models.Q(app_label='your_app_label', model='agency')
content_type = models.ForeignKey(ContentType, limit_choices_to=limit, related_name='user_content_type')
object_id = models.UUIDField()
content_object = GenericForeignKey('content_type', 'object_id')

您可以使用以下符号访问用户的品牌/创作者/代理机构:

User.objects.get(pk=1).content_object

根据 content_type,这将是 Brand/Creator/Agency 的实例。

https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/#django.contrib.contenttypes.fields.GenericForeignKey

根据您的评论更新

回复 1:使用电子邮件:

class User(models.Model):
...
email = models.EmailField(max_length=255, unique=True)
limit = models.Q(app_label='your_app_label', model='brand') |
models.Q(app_label='your_app_label', model='creator') |
models.Q(app_label='your_app_label', model='agency')
content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_type_choices, related_name='user_content_type')
content_object = GenericForeignKey('content_type', 'email')

注意:如果您采用这种方法,电子邮件在任何地方都不能是可为空的字段!此外,由于 email 字段现在已在多个位置声明,因此这种方法似乎很老套/错误;如果您重新分配内容对象,该值可能会更改。在其他三个模型中的每一个上使用离散的 UUIDField 链接 GenericForeignKey 会更清晰

回复 2:使用 account_type 字段:

ContentType 应该是对 Django 模型的引用;因此它需要的选择是模型而不是整数。limit_choices_to 的功能是执行过滤,这样所有可能的模型都不会显示为潜在的 GenericForeignKey

class ContentType(models.Model):
app_label = models.CharField(max_length=100)
model = models.CharField(_('python model class name'), max_length=100)
objects = ContentTypeManager()

但是,limit_choices_to 确实接受可调用项;因此您可以编写一个辅助方法,将您的 account_type 转换为正确的 Model

我不清楚这种转换应该如何进行;所以我把它留给你。

关于python - Django - 条件外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50187107/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com