说我有以下型号:
class Image(models.Model):
image = models.ImageField(max_length=200, upload_to=file_home)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey()
class Article(models.Model):
text = models.TextField()
images = generic.GenericRelation(Image)
class BlogPost(models.Model):
text = models.TextField()
images = generic.GenericRelation(Image)
Run Code Online (Sandbox Code Playgroud)
找到所有至少附有一个Image的文章的处理器和内存最有效的方法是什么?
我这样做了:
Article.objects.filter(pk__in=Image.objects.filter(content_type=ContentType.objects.get_for_model(Article)).values_list('object_id', flat=True))
Run Code Online (Sandbox Code Playgroud)
哪个有效,但除了丑陋之外需要永远.
我怀疑使用原始SQL有一个更好的解决方案,但这超出了我的范围.对于它的价值,上面生成的SQL如下:
SELECT `issues_article`.`id`, `issues_article`.`text` FROM `issues_article` WHERE `issues_article`.`id` IN (SELECT U0.`object_id` FROM `uploads_image` U0 WHERE U0.`content_type_id` = 26 ) LIMIT 21
Run Code Online (Sandbox Code Playgroud)
编辑: czarchaic的建议有更好的语法,但更糟(更慢)的性能.他的查询生成的SQL如下所示:
SELECT DISTINCT `issues_article`.`id`, `issues_article`.`text`, COUNT(`uploads_image`.`id`) AS `num_images` FROM `issues_article` LEFT OUTER JOIN `uploads_image` ON (`issues_article`.`id` = `uploads_image`.`object_id`) GROUP BY `issues_article`.`id` …Run Code Online (Sandbox Code Playgroud) 我正在使用object_list通用视图来快速列出一组文章.每篇文章都附有评论.该查询使用注释Count()数量的注释,然后order_by()使用注释的数字.
'queryset': Article.objects.annotate(comment_count=Count('comments')).order_by('-comment_count'),
Run Code Online (Sandbox Code Playgroud)
注释是django.contrib.comments框架的一部分,并通过通用关系附加到模型.我在我的文章模型中添加了显式反向查找:
class Article(models.Models):
...
comments = generic.GenericRelation(Comment, content_type_field='content_type', object_id_field='object_pk')
Run Code Online (Sandbox Code Playgroud)
问题是,这会计入"不活跃"的评论; 那些有is_public=False或is_removed=True.如何排除任何不活动的评论?
django django-models django-queryset django-managers generic-relationship
我运行代码来创建这个演示中的一般相关对象:http: //www.djangoproject.com/documentation/models/generic_relations/
一切都很好:
>>> bacon.tags.create(tag="fatty")
<TaggedItem: fatty>
>>> tag, newtag = bacon.tags.get_or_create(tag="fatty")
>>> tag
<TaggedItem: fatty>
>>> newtag
False
Run Code Online (Sandbox Code Playgroud)
但后来我对我的应用感兴趣的用例:
>>> tag, newtag = bacon.tags.get_or_create(tag="wholesome")
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/django/db/models/manager.py", line 123, in get_or_create
return self.get_query_set().get_or_create(**kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 343, in get_or_create
raise e
IntegrityError: app_taggeditem.content_type_id may not be NULL
Run Code Online (Sandbox Code Playgroud)
在查看其他代码后,我尝试了一堆随机的东西:
>>> tag, newtag = bacon.tags.get_or_create(tag="wholesome", content_type=TaggedItem)
ValueError: Cannot assign "<class 'generics.app.models.TaggedItem'>": "TaggedItem.content_type" must be a "ContentType" instance.
Run Code Online (Sandbox Code Playgroud)
要么:
>>> …Run Code Online (Sandbox Code Playgroud) class Foo(models.Model):
bar = models.CharField(max_length=300)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
class FooSerializer(serializers.ModelSerializer):
class Meta:
model = Foo
class FooViewSet(viewsets.ModelViewSet):
model = Foo
serializer_class = FooSerializer
Run Code Online (Sandbox Code Playgroud)
我现在可以将数据发布到如下所示的视图集:
{
bar: 'content',
content_type: 1
object_id: 5
}
Run Code Online (Sandbox Code Playgroud)
唯一让我烦恼的是,前端必须要注意contenttype id
相反,我希望能够将content_types名称发布为'User'作为content_type,并让后端确定id.
我想遍历我的Django模板中的泛型关系,类似于如何遍历FK关系.
Models.py
class Company(models.Model):
name = models.CharField(blank=True, max_length=100)
notes = models.TextField(blank=True)
class Address(models.Model):
address = models.TextField(max_length=200)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
Run Code Online (Sandbox Code Playgroud)
这在我的模板中似乎不起作用:
{{ company.address_set.all }}
Run Code Online (Sandbox Code Playgroud)
任何帮助表示赞赏.