Используйте
limit_choices_to. Принципиально решение будет выглядеть примерно так:
from django.db.models import Q
class Slider(models.Model):
# ...
content_type = models.ForeignKey(
ContentType,
limit_choices_to=Q(app_label='app_1', model='modelclass1') | Q(app_label='app_2', model='modelclass2')
)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
# ...
Нового тут особо ничего не придумаешь, но есть есть возможность украсить код, например, написав функцию (
limit_choices_to
может принимать callable-объект, возвращающий
dict
или
Q
):
from operator import or_ as OR
from functools import reduce
from django.apps import apps
from django.db.models import Q
def limit(*models):
"""
Динамически построит выражение Q для списка заданных в аргументе моделей.
"""
return reduce(OR, [Q(
app_label=apps.get_model(m)._meta.app_label,
model=apps.get_model(m)._meta.model_name) for m in models
])
class Slider(models.Model):
# ...
content_type = models.ForeignKey(
ContentType,
limit_choices_to=limit('app_1.ModelClass1', 'app_2.ModelClass2'),
)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
# ...
Можно пойти ещё дальше и написать собственное поле, заменяющее три поля generic одним. На мой взгляд, код будет лаконичнее:
class Slider(models.Model):
content_object = LimitedGenericForeignKey(
allowed_models=['app_1.ModelClass1', 'app_2.ModelClass2']
)
Но это оставлю на домашнее задание :)