繁体   English   中英

如何使用父字段限制查询集?

[英]How can I limit the queryset using a parent field?

我必须通过父模型字段来限制。

models.py

class Blog(Model):
    max_posts       = IntegerField(verbose_name=u"Limite Posts", help_text=u"Número de posts máximo DESSE BLOG para serem exibidos na home.")

class Post(Model):
    title           = CharField(max_length=200, verbose_name=u"Título")

我想在我的模板上得到这样的东西:

-博客A(max_posts = 2)

Item 1

Item 2

-博客B(max_posts = 3)

Item 1

Item 2

Item 3

所以我尝试了一下

views.py

Post.objects.annotate(blog__max_posts=Count('blog__max_posts')).filter(blog__published=True)

但这并不像预期的那样工作。 我怎样才能做到这一点?

如果添加缺少的外键:

class Blog(Model):
    name = CharField(max_length=255)
    max_posts = IntegerField(verbose_name=u"Limite Posts", help_text=u"Número de posts máximo DESSE BLOG para serem exibidos na home.")

class Post(Model):
    blog = ForeignKey(Blog)
    title = CharField(max_length=200, verbose_name=u"Título")

您可以通过每个博客一个db-hit来获取帖子:

blogs = Blog.objects.filter(published=True)
posts = {b:b.post_set.all()[:b.max_posts] for b in blogs}

您可能需要在切片之前添加order_by

然后可以将模板编写为:

{% for blog, blogposts in posts.items %}
    <h1>{{ blog.name }} (max_posts={{ blog.max_posts }})</h1>
    <ul>
    {% for post in blogposts %}
       <li>{{ post }}</li>  {# probably something more fancy here.. #}
    {% endfor %}
    </ul>
{% endfor %}

不确定django是否为您提供了此类内置功能,因此您需要自己购买。 为此,请在Blog模型中定义ForeignKey关系:

class Blog(Model):
  # Other fields 
  post = models.ForeignKey(Post)

通过向Blog模型添加add_post方法来达到预期的结果:

def add_post(self, post):
    # assume you have max_posts_count defined
    if self.post_set.count() >= max_posts_count:
         raise Exception("Too many posts")

    self.post_set.add(post)

获得相同结果的另一种方法是使用Django pre_save信号来检查posts数是否达到最大值,如果在pre_save方法中raise Exception或允许保存。

在与博客相关的帖子上放置一个ForeignKey字段。

在该字段validate_max_posts上使用验证器,如下所示:

from django.core.exceptions import ValidationError

class Blog(Model):
    max_posts = IntegerField(verbose_name=u"Limite Posts", help_text=u"Número de posts máximo DESSE BLOG para serem exibidos na home.")

def validate_max_posts(value):
    blog_id = None
    if type(value) is not Blog:   # admin panel
        blog_id = value

    if type(value) is Blog:       # service : DRF
        blog_id = value.id

    post_count = Post.objects.filter(blog__id = blog_id).count()
    max_posts = Blog.objects.get(pk=blog_id)
    if post_count > max_posts:
        raise ValidationError(u'Exceed max posts count')

class Post(Model):
    title = CharField(max_length=200, verbose_name=u"Título")
    blog = models.ForeignKey(Blog,validators=[validate_max_posts])

暂无
暂无

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

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