【问题标题】:How to use abstract model as a ForeignKey in Django?如何在 Django 中使用抽象模型作为 ForeignKey?
【发布时间】:2018-12-15 06:43:31
【问题描述】:

我有一个这样的模型:

class A(models.Model):
     ....
     ....
     class Meta:
        abstract = True

class B(A):
     blah..
     blah..

class C(A):
     blah..
     blah..

只是我想在不同的模型中使用 Model A 作为 ForeignKey 像这样:-

class X(models.Model):
       """
       I want to use like this, But i'm getting error
       """
       name = models.ForeignKey(A)

但我收到错误:

apis.X.name: (fields.E300) 字段定义与模型“A”的关系, 要么没有安装,要么是抽象的。

我做错了吗? 如何避免这种情况?

提前致谢

【问题讨论】:

    标签: python django python-3.x django-models


    【解决方案1】:

    在您的 Meta 中设置 Abstract=True 意味着您的数据库中不会创建任何表。

    来自docs

    抽象基类在你想把一些常见的 信息转化为许多其他模型。你写你的基类 并将 abstract=True 放在 Meta 类中。那么这个模型就不会 用于创建任何数据库表。相反,当它被用作基础时 其他模型的类,其字段将添加到子模型的字段中 类。

    要解决您的问题,您应该使用模型 B 或模型 C 的外键,因为它们将代表数据库中的实际表。您的抽象模型应仅用于继承目的。

    【讨论】:

    • 太好了,只是我想尽量避免:name1 = models.ForeignKey(B),name2 = models.ForeignKey(C),我该如何避免呢?
    • @JustChill 嗯,这更像是一个数据库设计问题。根据您正在处理的实际内容,可能会有更简洁的方法。
    • 我找到了解决办法,谢谢你的回答,
    【解决方案2】:

    Django 提供了一种特殊的字段类型(GenericForeignKey),它可以解决这个问题,并允许与任何模型建立关系,无论是抽象模型。

    请参阅 GenericForeignKey Docs 了解更多信息。

    from django.contrib.contenttypes.fields import GenericForeignKey
    from django.contrib.contenttypes.models import ContentType
    from django.db import models
    
    class TaggedItem(models.Model):
        tag = models.SlugField()
        content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
        object_id = models.PositiveIntegerField()
        content_object = GenericForeignKey('content_type', 'object_id')
    
    def __str__(self):
        return self.tag
    

    或:

    您可以通过在其中使用abstract = True 将自定义模型实现为基本模型,在您的子模型中您可以将其用作ForeignKey

    实现是这样的:

    class X(models.Model):
       """
       I want to use like this, But i'm getting error
       """
       name = models.ForeignKey(A)
       class Meta:                                                             
           abstract = True                                                     
    return A                                                   
    

    对于这个转到abstract-base-classes Docs:

    【讨论】:

    • 我找到了解决办法,谢谢你的回答
    【解决方案3】:

    我找到了解决办法:

    name = models.ForeignKey(A, null=True, blank=True, on_delete=models.SET_NULL, related_name="content_%(class)s")
    

    【讨论】:

    • 你在模型类中使用了Abstract= True吗?
    • 是的,在我的基础模型中,而不是在 X 模型中
    • @MrSingh 你能检查一下我的question吗?
    猜你喜欢
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 2015-08-01
    • 2018-06-16
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多