Campo ForeignKey relacionado ao modelo abstrato no Django

Eu tenho esse modelo:

class BaseModel(models.Model): .... class Meta: abstract = True class ModelA(BaseModel): .... class ModelB(BaseModel): .... class MyExtModel(models.Model) myfield = models.ForeignKey(BaseModel) 

Mas isso não está correto porque eu tenho o BaseModel como o Abstract . De fato, eu tenho um erro quando tento o comando makemigration .

O erro é:

 ERRORS: myapp.MyExtModel.myfield: (fields.E300) Field defines a relation with model 'BaseModel', which is either not installed, or is abstract. 

Existe uma maneira de usar um modelo básico abstrato?

Eu também tentei usar:

 myfield = models.ForeignKey(BaseModel, related_name="%(app_label)s_%(class)s_related") 

Não é possível instalar foreign keys para abstrair modelos no Django. Você pode, no entanto, instalar Chaves Estrangeiras em uma class base não abstrata. A única limitação é que a relação de chave estrangeira reversa retornará as instâncias da class base. Você pode contornar essa limitação usando o django-polymorphic .

O Django Polymorphic permite que você consulte os objects da class base, mas recupera as instâncias da class filho:

 >>> Project.objects.create(topic="Department Party") >>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner") >>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter") >>> Project.objects.all() [ , ,  ] 

Para usar o polimorfo django, você só precisa declarar seus modelos com o modelo polimórfico como class base:

 from django.db import models from polymorphic.models import PolymorphicModel class ModelA(PolymorphicModel): field1 = models.CharField(max_length=10) class ModelB(ModelA): field2 = models.CharField(max_length=10) class ModelC(ModelB): field3 = models.CharField(max_length=10) 

Chaves estrangeiras também retornarão as instâncias da class filha, que é o que você precisa, eu suponho:

 # The model holding the relation may be any kind of model, polymorphic or not class RelatingModel(models.Model): many2many = models.ManyToManyField('ModelA') # ManyToMany relation to a polymorphic model >>> o=RelatingModel.objects.create() >>> o.many2many.add(ModelA.objects.get(id=1)) >>> o.many2many.add(ModelB.objects.get(id=2)) >>> o.many2many.add(ModelC.objects.get(id=3)) >>> o.many2many.all() [ , ,  ] 

Tenha em conta que estas consultas terão um desempenho ligeiramente inferior .

Quando enfrentei uma situação como essa, onde tenho que fazer ForeignKeys para modelos diferentes, escolho usar GenericForeignKey para verificar documentos oficiais aqui: Django ContentTypes: Generic Relations

Os documentos explicam muito bem como usá-lo:

 from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType class TaggedItem(models.Model): tag = models.SlugField() content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') def __str__(self): # __unicode__ on Python 2 return self.tag 
  • O campo content_type armazena o modelo para o qual a chave estrangeira genérica está apontando

  • O campo object_id armazena o ID da chave estrangeira,

  • O campo content_object ajuda você a acessar diretamente o object relacionado com base nos outros 2 campos

Não é a melhor solução, mas me poupa em alguns projetos

Exemplo de uso:

 from django.contrib.auth.models import User guido = User.objects.get(username='Guido') t = TaggedItem(content_object=guido, tag='bdfl') t.save() t.content_object  

Além da boa resposta com GenericForeignKey , com a qual eu não estou bem familiarizado, às vezes (às vezes, sempre que possível), vale a pena simplificar seus modelos usando relacionamentos um-para-um com seu modelo ‘base’.

Facilita o gerenciamento de foreign keys depois disso. Se bem me lembro, chave estrangeira em uma class abstrata não é possível.

Intereting Posts