Как использовать абстрактную модель в качестве ForeignKey в Django?

У меня такая модель:

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

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

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

Просто я хочу использовать модель 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) Field defines a relation with model 'A', which is either not installed, or is abstract.

Я делаю что-то неправильно? Как этого избежать?

заранее спасибо

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
0
3 723
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Установка Abstract=True в вашем Meta означает, что в вашей базе данных не создается таблица.

Из документы:

Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put abstract=True in the Meta class. This model will then not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class.

Чтобы решить вашу проблему, вам следует использовать внешний ключ либо для модели B, либо для модели C, поскольку они будут представлять фактические таблицы в вашей базе данных. Ваша абстрактная модель должна использоваться только для целей наследования.

Отлично, просто я хочу попытаться избежать: name1 = models.ForeignKey (B), name2 = models.ForeignKey (C), как я могу этого избежать?

Mr Singh 06.07.2018 18:14

@JustChill Ну, это скорее вопрос дизайна базы данных. В зависимости от фактического содержания, с которым вы работаете, могут быть более чистые способы.

dfundako 06.07.2018 18:17

Я нашел решение, спасибо за ответ,

Mr Singh 09.07.2018 08:41

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, а в своих дочерних моделях вы можете использовать ее как Иностранный ключ.

Реализация будет примерно такой:

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 Документы:

Я нашел решение, спасибо за ответ

Mr Singh 09.07.2018 08:40
Ответ принят как подходящий

Я нашел решение:

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

Вы использовали Abstract= True в своем классе моделей?

ans2human 09.07.2018 09:23

Да в моей базовой модели, а не в модели X

Mr Singh 09.07.2018 09:33

@MrSingh, не могли бы вы проверить мой вопрос?

Shahriar.M 17.12.2020 16:45

Другие вопросы по теме