Django分页(获取页面对应的对象) [英] Django pagination (get page no. corresponding to the object)

查看:240
本文介绍了Django分页(获取页面对应的对象)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个分页我正在尝试从一个对象页面中获取索引页(反向分页)



get_paginated_posts返回模型的分页符 Post

  class PostManager(models.Manager):
def get_paginated_posts(self,request = None):
如果请求和request.user.has_perm('blog.change_post'):
posts = super(PostManager,self).filter(is_update = False)
else:
posts = super(PostManager,self).filter(publish = True,is_update = False)
返回Paginator(posts,POSTS_PER_PAGE)


这是我的模型

  class Post(models.Model):



def get_page(self,request = None):
paginator = Post.objects.get_paginated_posts(request)
for i in range(1,paginator.num_pages + 1):
如果自己在paginator.page(i).object_list:
return i
pass
return False

我关心的是在get_page函数中的 Post.objects.get_paginated_posts 调用。

是对的从实例调用发布类?有没有其他更好的方法可以实现?

为什么我不能调用 super(Post,self).objects.get_paginated_posts 做同样的事情?

我明白,$ code> self.objects.get_paginated_posts 不会因为对象的访问而无法使用经理。



已解决



Tomasz Elendt建议的最终代码:


$ b $

def get_paginated_posts(self,user = None):
如果user和user.has_perm('blog.change_post '):
posts = super(PostManager,self).filter(is_update = False)
else:
posts = super(PostManager,self).filter(publish = True,is_update = False )
return Paginator(posts,POSTS_PER_PAGE)

class Post(models.Model):

def get_page(self,request = None):
return self._default_manager.filter(is_update = False,time__gt = self.time).count()/ POSTS_PER_PAGE +1
#现在一行:P


解决方案

这不是最好的想法你在做。尝试想象有多少查询会被翻译成 - 在最坏的情况下,您需要从数据库中检索所有用户的帖子!



我假设你有您的 Post 模型( Paginator 使用的模式)中的某些预定义顺序。使用它来获取该特定帖子记录之前的用户帖子数。如果您将该号码除以 POSTS_PER_PAGE 值,您将得到您的页码。



IMHO使用 PostManager 发布方法可以。不正确的是,您正在传递请求对象,而我认为您应该使用 user_id (并且权限检查应该是视图逻辑的一部分)。 / p>

编辑:示例

  from django .db导入模型
从django.contrib.auth.models import User

POSTS_PER_PAGE = 10

class Post(models.Model):
d
>> from datetime import datetime,timedelta
>> from django.db import connection
>> from django.conf import settings
>>>
>>> user = User.objects.create_user(test,test@domain.com)
>>>对于我在xrange(100)中:
... p = Post.objects.create(author = user,
... pub_date = datetime.now() - timedelta(hours = i))
>>> post = Post.objects.all()[68]
>>> settings.DEBUG = True#monkey-patching s ettings - 丑陋的
>>>> connection.queries = []#清除以前的查询
>>> post.get_page()
7
>>> len(connection.queries)#打印get_page调用的查询号
1

pub_date = models.DateTimeField(auto_now_add = True)
author = models。 ForeignKey(User)
class Meta:
ordering = [-pub_date]

def get_page(self):
return self._default_manager.filter(author__id = self.author_id).filter(
pub_date__gt = self.pub_date).count()/ POSTS_PER_PAGE + 1


I have a paginate I am trying to get the index page from an object page (sort of pagination in reverse)

The get_paginated_posts returns a paginator for the model Post:

class PostManager(models.Manager):
    def get_paginated_posts(self, request=None):
        if request and request.user.has_perm('blog.change_post'):
            posts = super(PostManager, self).filter(is_update=False)
        else:        
            posts = super(PostManager, self).filter(publish=True, is_update=False)
        return Paginator(posts, POSTS_PER_PAGE)
    .
    .

This is my model

class Post(models.Model):
    .
    .
    .
    def get_page(self, request=None):
        paginator = Post.objects.get_paginated_posts(request)
        for i in range(1, paginator.num_pages+1):
            if self in paginator.page(i).object_list:                
                return i
            pass
        return False 

My concern is the Post.objects.get_paginated_posts call in the get_page function.
Is it right to call Post class from an instance? Is there any other better way to do this possible?
Why cannot I call super(Post, self).objects.get_paginated_posts to do the same?
I understand that self.objects.get_paginated_posts wont work because of absent access for the object to its manager.

Solved

Final code as suggested by Tomasz Elendt:

class PostManager(models.Manager):
    def get_paginated_posts(self, user=None):
        if user and user.has_perm('blog.change_post'):
            posts = super(PostManager, self).filter(is_update=False)
        else:        
            posts = super(PostManager, self).filter(publish=True, is_update=False)
        return Paginator(posts, POSTS_PER_PAGE)

class Post(models.Model):
    .
    def get_page(self, request=None):
        return self._default_manager.filter(is_update = False, time__gt=self.time).count()/POSTS_PER_PAGE +1 
        #Just a one line now :P 

解决方案

It's not the best idea what you're doing. Try to imagine how many queries it'll be translated to -- in the worst case you'd need to retrieve all user's posts from database!

I assume that you have some predefined ordering in your Post model (the one that Paginator uses). Use that to obtain the number of user's posts that precede that specific post record. If you divide that number by the POSTS_PER_PAGE value you'll get your page number.

IMHO using PostManager in Post methods is ok. What's not ok is that you're passing request object to it while I think you should use user_id for that (and permission checking should be really part of a view logic).

EDIT: example

from django.db import models
from django.contrib.auth.models import User

POSTS_PER_PAGE = 10

class Post(models.Model):
    """
    >>> from datetime import datetime, timedelta
    >>> from django.db import connection
    >>> from django.conf import settings
    >>>
    >>> user = User.objects.create_user("test", "test@domain.com")
    >>> for i in xrange(100):
    ...     p = Post.objects.create(author=user,
    ...                             pub_date=datetime.now() - timedelta(hours=i))
    >>> post = Post.objects.all()[68]
    >>> settings.DEBUG = True    # monkey-patching settings - ugly
    >>> connection.queries = []  # cleaning previous queries
    >>> post.get_page()
    7
    >>> len(connection.queries)  # print number of queries of `get_page` call
    1
    """
    pub_date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(User)
    class Meta:
        ordering = ["-pub_date"]

    def get_page(self):
        return self._default_manager.filter(author__id=self.author_id).filter(
            pub_date__gt=self.pub_date).count() / POSTS_PER_PAGE + 1

这篇关于Django分页(获取页面对应的对象)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆