Django - InheritanceManager 不工作
Django - InheritanceManager is not working
我有以下简单的 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)
当我在 url 中传递端点 posts/
时,将触发此视图,它应该只给我 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/"
}
]
为什么会这样?我浏览了官方文档 here 。有人可以帮忙
为了完整起见,我的 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__'
从文档来看,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)
部分
我有以下简单的 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)
当我在 url 中传递端点 posts/
时,将触发此视图,它应该只给我 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/"
}
]
为什么会这样?我浏览了官方文档 here 。有人可以帮忙
为了完整起见,我的 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__'
从文档来看,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)
部分