【问题标题】:Django - use same column for two foreign keysDjango - 对两个外键使用同一列
【发布时间】:2016-04-28 10:22:34
【问题描述】:

我有三个模型:

class UserProfile:
   user_id = OneToOneField(User, related_name='profile')
   name = CharField

class User:
   # standard django model

class Channel:
   owner = ForeignKey(User)

现在,我想对用户名进行频道过滤。所以我能做的是:

Channel.objects.filter(owner__profile__name__icontains='foo')

但是这会加入 User 表,然后加入 UserProfile,这不是最好的,因为我想在 user_id 上加入 UserProfile 表(我会加入一个而不是两个)

我尝试为模型添加另一个外键,如下所示:

class Channel:
    owner = models.ForeignKey(
        User,
        db_column='owner_id',
    )
    owner_profile = models.ForeignKey(
        UserProfile,
        db_column='owner_id',
        to_field='user_id')

但 Django 不喜欢它....

posts.Post: (models.E007) Field 'owner_profile' has column name 'owner_id' that is used by another field.
    HINT: Specify a 'db_column' for the field.

有什么干净的解决方法吗?

【问题讨论】:

  • 为此,您必须假设 User 和 UserProfile 表具有相同的 ID 值。没有理由认为这是真的。
  • 不,注意第二个 ForeignKey 上的 to_field
  • 好问题,遇到了同样的问题 - 我有唯一的 uuid 值,在三个不同的表 - A、B、C 中提到,我想要从 C 到的 ORM 引用A 和 B 对象都使用 C 的相同底层列。
  • 遇到同样的问题...

标签: python django foreign-keys


【解决方案1】:

Django content type 框架可以解决问题

在你的情况下:

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType

class Channel(models.Model):
    owner_ct = models.ForeignKey(to=ContentType, on_delete=models.CASCADE, blank=True, null=True) # foreign key table indicator (User,Profile) in your case
    owner_content = models.CharField(max_length=64, blank=True, null=True) # uuid(foreign key) will be placed here as string
    owner_object = GenericForeignKey('owner_ct', 'owner_content') # bridge to object

class User(models.Model):
    channels = GenericRelation(to='Channel', object_id_field='owner_content', content_type_field='owner_ct',related_query_name='channels') # User.channels will be available

class Profile(models.Model):
    channels = GenericRelation(to='Channel', object_id_field='owner_content', content_type_field='owner_ct',related_query_name='channels') # Profile.channels will be available
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-04
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 2010-10-07
    相关资源
    最近更新 更多