使用参数例如在外键上过滤查询集。作为观点

时间:2018-03-31 23:04:33

标签: django foreign-keys django-queryset

我正在尝试构建一个灵活的查询集,根据我使用的参数提供结果大小,但目前我只能通过外键访问该数据。这是设置。

我的第一张桌子是一组博客文章" - 该模型非常自我解释:

class BlogPost(models.Model):
    title = models.CharField(max_length=100)
    dateStamp = models.DateTimeField(auto_now_add=True)
    post = models.TextField()

第二个是一个表,以一对多的关系保存所有帖子的所有图像:

class BlogImageSeqFilter(models.Manager):
    def get_querySet(self):
        ## slice the first three images with sequence between 1 and 3
        return self.filter(sequence__gte=1, sequence__lte=3)[:3]

class BlogImage(models.Model):
    blog = models.ForeignKey(BlogPost, null=True, on_delete=models.SET_NULL)
    img = models.ImageField(upload_to=imgFolder, blank=True)
    sequence = models.IntegerField(null=False, blank=False, default=0)

    objects = BlogImageSeqFilter() ## Custom Manager class BlogImageSeqFilter

(经理方法在我的问题中稍晚出现 - 我甚至不知道到目前为止使用它是否是正确的方法......)

在我看来,这组博客文章在html tmeplate的呈现中包含在内容中:

def blogPage(request, proj):
    ## Limit to the newest 5 posts
    blogs = project.blogpost_set.all().order_by("-dateStamp")[:5]
    return render(request, 'blog/blogPage.html', {"blogs":blogs})

因此,在我的模板中,我将每个博客帖子显示在一个单独的容器中,并使用blogimage_set包含与该博客相关的一组图像。简化我到目前为止所做的事情将是:

{% for post in blogs %}
    <div>
        {{post.title}}
        {{post.post}}
        {% for image in post.blogimage_set.get_querySet %}
            <img src="yada yada {{image.img}} yada yada></img>
        {% endfor %}
    </div>
{% endfor %}

现在,我坚持了下来。我想更改模型和视图,以便我可以以某种方式传递参数来限制每个帖子中的项目数量(据我所知,你可以真正地从模板中反向传递参数,除非你开始写使用自定义模板标签,在这种情况下我不想做,因为我确信有更好的方法,我想学习这种方式。)

我想要足够灵活的东西,我可以在其他地方重新使用博客图片,使用不同的参数来表示返回的图像数量。但它并不像&#34那么简单;给我表中的第一张x图像&#34;。

假设我上传了10张图片,我将从1-10分配所有序列#s(因此模型中的&#39;序列&#39;字段)。但该序列可能与我上传的顺序不同。总的来说,我希望能够在给定的视图中选择来自10个集合的x个图像将出现在该博客文章中。 &#34;在seq#1和#3&#34之间给我图像;或者&#34;从seq#4&#34;开始给我5张图片。什么的。

我实现此功能的第一个增量尝试是创建BlogImageSeqFilter Manager及其方法,该方法提供三个序列在1到3之间的有限查询集。

更改模型(或者更确切地说是管理器/其方法)以接受参数看起来就像一个简单的位。但我无法弄清楚如何修改视图和模板以使用参数,这样我就可以包含&#34; blogImages&#34;在渲染的上下文中,同时仍然在模板中显示它们如上所示(&#34;对于给定博客中的每个帖子...为该帖子的每个x图像做一些html和... ...做更多的HTML&#34;)。

我很欣赏更改传统&#34;博客文章中显示的图像&#34;在最初发布之后并不是一个非常有意义的上下文 - 但正如所提到的,我希望这种灵活性可以在其他地方使用,或者在以后将代码重用于其他内容。而且我有一种感觉因为知识/技能差距或我目前正在工作的方式存在更广泛的问题而陷入困境,所以不妨在这里找出它。

1 个答案:

答案 0 :(得分:1)

我认为你过分复杂了。如果要控制在特定上下文中显示的图像数量,则可以在使用时slice图像查询集。

因此,在您的模板中,您可以执行以下操作来渲染前三个图像:

{% for image in post.blogimage_set.all|slice:":3" %}
    <img src="yada yada {{image.img}} yada yada></img>
{% endfor %}

请注意querysets are lazy,因此这只会从您的数据库中获取前三张图片。

如果您想在其他地方使用更多/更少的图像,则只需对查询集进行不同的切片。我认为您不需要自定义模型管理器来实现这一目标。