При создании объекта прокси-класс назначается на основе поля (полей) базовой модели

Я надеюсь, что смогу создать объект, используя базовую модель, но чтобы этот объект фактически был создан как прокси-класс в зависимости от поля (полей) объекта.

Например, для следующих моделей:

class Animal(models.Model):
    species = models.CharField()

class Cat(Animal):
    class Meta:
        proxy = True

class Dog(Animal):
    class Meta:
        proxy = True

Как я могу настроить его так, чтобы

cat = Animal.objects.create(species="cat")
dog = Animal.objects.create(species="dog")

Animal.objects.all() # Returns queryset of [cat, dog]
Cat.objects.all() # Returns queryset of [cat]
Dog.objects.all() # Returns queryset of [dog]

Вам следует создать настраиваемый менеджер для каждого прокси.

class Animal(models.Model):
    species = models.CharField()

class CatManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(species='cat')

class DogManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(species='dog')

class Cat(Animal):
    objects = CatManager()
    class Meta:
        proxy = True

class Dog(Animal):
    objects = DogManager()
    class Meta:
        proxy = True

Определите пользовательский менеджер для Animal, который будет фильтровать набор запросов на основе вида. Здесь мы будем использовать имя класса в качестве основы для названия вида.

class AnimalManager(models.Manager):
    def get_queryset(self):
        if self.model is Animal:
            return super().get_queryset()
        return super().get_queryset().filter(species=self.model.__name__.casefold())

class Animal(models.Model):
    objects = AnimalManager()
    species = models.CharField(max_length=100)

class Cat(Animal):
    class Meta:
        proxy = True

class Dog(Animal):
    class Meta:
        proxy = True

Выход

>>> from my_app.models import *
>>>
>>> # Create the animals
>>> Animal.objects.create(species="cat")
<Animal: Animal object (1)>
>>> Animal.objects.create(species="dog")
<Animal: Animal object (2)>
>>> Animal.objects.create(species="cat")
<Animal: Animal object (3)>
>>> Animal.objects.create(species="cat")
<Animal: Animal object (4)>
>>> Animal.objects.create(species="dog")
<Animal: Animal object (5)>
>>>
>>> # Query the animals
>>> Animal.objects.all()
<QuerySet [<Animal: Animal object (1)>, <Animal: Animal object (2)>, <Animal: Animal object (3)>, <Animal: Animal object (4)>, <Animal: Animal object (5)>]>
>>> Cat.objects.all()
<QuerySet [<Cat: Cat object (1)>, <Cat: Cat object (3)>, <Cat: Cat object (4)>]>
>>> Dog.objects.all()
<QuerySet [<Dog: Dog object (2)>, <Dog: Dog object (5)>]>
Вернуться на верх