Django - InheritanceManager не работает - PullRequest
0 голосов
/ 18 июня 2019

У меня есть следующий простой models.py файл:

from django.db import models
from model_utils.managers import InheritanceManager

class Clique(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=100, blank=False)

class Post(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    headline = models.TextField()
    clique = models.ForeignKey(Clique,
                               on_delete=models.CASCADE,
                               blank=True,
                               null=True)
    objects = InheritanceManager()
    def __str__(self):
        return self.headline


class VideoPost(Post):
    video = models.BooleanField(default=True)


class ImagePost(Post):
    image = models.BooleanField(default=True)

Итак, есть модель Clique, которая может содержать несколько Post экземпляров. Экземпляры Post могут быть ImagePost или VideoPost. Следовательно, ImagePost и VideoPost оба наследуют Post.

Теперь, допустим, я хочу получить экземпляры подкласса ImagePost. Итак, у меня есть следующий вид в моем файле views.py:

class PostList(generics.ListAPIView):
    serializer_class = PostSerializer

    def get_queryset(self):
        return Post.objects.select_subclasses(ImagePost)

Когда я передаю конечную точку posts/ в URL, тогда это представление будет срабатывать, и оно должно давать мне только ImagePost экземпляров, верно? Но я также получаю VideoPost экземпляров из базы данных:

[
    {
        "clique": "http://127.0.0.1:8000/cliques/1/", 
        "comment_set": [], 
        "created": "2019-06-18T09:52:47.929623Z", 
        "headline": "FirstImagePost", 
        "id": 1, 
        "url": "http://127.0.0.1:8000/posts/1/"
    }, 
    {
        "clique": "http://127.0.0.1:8000/cliques/1/", 
        "comment_set": [], 
        "created": "2019-06-18T09:53:20.266653Z", 
        "headline": "FirstVideoPost", 
        "id": 2, 
        "url": "http://127.0.0.1:8000/posts/2/"
    }
]

Почему это происходит? Я прошел через официальный документ здесь . Может ли кто-нибудь помочь

Просто ради полноты мой файл serializers.py выглядит следующим образом:

from rest_framework import serializers
from posts.models import Post, VideoPost, ImagePost, Clique

class CliqueSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Clique
        fields = ('id', 'name', 'post_set')
        read_only_fields = ('post_set', )

class PostSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Post
        fields = ('url', 'id', 'created', 'headline', 'clique', 'comment_set',)
        read_only_fields = ('comment_set',)


class VideoPostSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = VideoPost
        fields = '__all__'


class ImagePostSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = ImagePost
        fields = '__all__'

1 Ответ

1 голос
/ 18 июня 2019

Из документации кажется, что select_subclasses не фильтрует вас по типу подкласса, он конвертирует его в подкласс, только если он соответствует тому, что вы указали.

в вашем случае

Post.objects.select_subclasses(ImagePost)

преобразует весь ImagePost в экземпляр ImagePost, оставляя остальные как объект Post, но не отфильтровывает их.

из документа здесь:

nearby_places = Place.objects.select_subclasses("restaurant")
# restaurants will be Restaurant instances, bars will still be Place instances

В вашем случае вы можете просто сделать:

Post.objects.filter(imagepost__image=True).select_subclasses(ImagePost)

Хотя я не думаю, что вам нужна select_subclasses(ImagePost) часть

...