2015-04-17 2 views
1

У меня есть куча моделей Django, которые наследуются от полиморфной модели django-polymorphic. В другой модели у меня есть отношение ForeignKey к ContentType, которое я хотел бы ограничить моделями, которые наследуются от определенного базового класса.Фильтрация ContentType ForeignKey с использованием django-polymorphic

Пример:

from django.db import models 
from polymorphic import PolymorphicModel 
from django.contrib.contenttypes.models import ContentType 

class MagicBaseModel(PolymorphicModel): 
    def do_magic(self): 
     # ... 

class MagicObjectA(MagicBaseModel): 
    def do_magic(self): 
     super(MagicObjectA, self).do_magic(self) 
     # ... 

class MagicObjectB(MagicBaseModel): 
    def do_magic(self): 
     super(MagicObjectB, self).do_magic(self) 
     # ... 

class NonMagicObject(models.Model): 
    # ... 

class MagicAction(models.Model): 
    magic_object_type = models.ForeignKey(ContentType) 
    # ... 

В приведенном выше примере, я хотел бы ограничить MagicAction.magic_object_type так, что только MagicObjectA и MagicObjectB доступны как выбор.

Я попытался с помощью limit_choices_to так:

magic_object_type = models.ForeignKey(ContentType, limit_choices_to=Q(polymorphic_ctype=ContentType.objects.get_for_model(MagicBaseModel))) 

Тем не менее, кажется, что вы не можете выполнить этот запрос в течение модели инициализации как модель ТипСодержимого еще не готова.

Любые идеи лучшего способа я мог бы подойти к этому?

ответ

0

Я хотел бы попробовать следующее, вдохновленный здесь: Choose queryset for limit_choices_to based on object fields:

Ваш запрос для двух типов контента пока не может быть оценена в функции ForeignKey, так как БД будет еще не готов.

Следовательно, вам нужно использовать функцию вместо этого, которая при необходимости будет выбирать два варианта.

Затем в этой функции вы можете фильтровать в поле «модель» экземпляра типа содержимого.

Как так:

def get_choices(): 
    query_a = ContentType.objects.filter(
     model=ContentType.objects.get_for_model(MagicObjectA).model) 
    query_b = ContentType.objects.filter(
     model=ContentType.objects.get_for_model(MagicObjectB).model) 
    return {'magic_object_type': query_a | query_b} 

Где в вашем объявлении поля вы можете обратиться к этой функции, например, так:

magic_object_type = models.ForeignKey(ContentType, limit_choices_to=get_choices) 
Смежные вопросы