简体   繁体   English

Django-InheritanceManager无法正常工作

[英]Django - InheritanceManager is not working

I have the following simple models.py file: 我有以下简单的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)

So, there is a Clique model which can contain multiple Post instances. 因此,有一个Clique模型可以包含多个Post实例。 The Post instances can be ImagePost or VideoPost . Post实例可以是ImagePostVideoPost Therefore, ImagePost and VideoPost both inherit Post . 因此, ImagePostVideoPost都继承Post

Now, let's say I want to retrieve the ImagePost subclass instances. 现在,假设我要检索ImagePost子类实例。 So, I have the following view in my views.py file: 因此,我的views.py文件中具有以下视图:

class PostList(generics.ListAPIView):
    serializer_class = PostSerializer

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

When I pass the endpoint posts/ in the url, then this view will be triggered and it should give me only the ImagePost instances, right ? 当我在url中传递端点posts/时,将触发此视图,并且该视图应该只给我ImagePost实例,对吗? But I also get the VideoPost instances from the database: 但是我还从数据库中获取了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/"
    }
]

Why is this happening ? 为什么会这样呢? I walked through the official doc here . 我在这里浏览了官方文件。 Can somebody help 有人可以帮忙吗

Just for the sake of completeness, my serializers.py file looks like the following: 为了完整起见,我的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__'

From the documentation, it seems like select_subclasses does not filter by subclass type for you, it only converts it to the subclass if it matches what you supplied. 从文档中看来, select_subclasses似乎并没有为您提供子类类型的筛选,它仅在与您提供的内容匹配时才将其转换为子类。

in your case 在你的情况下

Post.objects.select_subclasses(ImagePost)

will convert all ImagePost to ImagePost instance, leaving the other ones as Post object, it doesn't filter it out. 会将所有ImagePost转换为ImagePost实例,将其他实例保留为Post对象,但不会将其过滤掉。

from the doc here: 从这里的文档:

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

In your case you can simply do: 就您而言,您可以简单地执行以下操作:

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

Though i don't think you need the select_subclasses(ImagePost) part 虽然我认为您不需要select_subclasses(ImagePost)部分

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM