注意类定义属性和方法的顺序

详见我的提问“自定义分页组件类无法正常实例化”。

为了方便做浏览器的分页组件自定义了一个 CustomPaginator 类,paginator.py代码如下:


class CustomPaginator:
    def __init__(self, queryset, page_number, items_per_page=10, visible_page_count=7):
        """
        初始化分页器
        :param queryset: 数据查询集
        :param page_number: 当前页码
        :param items_per_page: 每页显示的条目数
        :param visible_page_count: 分页导航中可见的页码数量
        """
        self.queryset = queryset
        self.total_items = self.queryset.count()    # 查询的数据(对象)个数

        self.page_number = self._validate_page_number(page_number)
 
        self.items_per_page = items_per_page
        self.visible_page_count = visible_page_count
        self.total_pages = self._calculate_total_pages()    # 分页个数
 
    def _validate_page_number(self, page_number):
        """
        校验并调整页码
        :param page_number: 用户输入的页码
        :return: 合法的页码,(不超过最大页码,不小于1)
        """
 
        return max(1, min(page_number, self._calculate_total_pages())) 

 
    def _calculate_total_pages(self):
        """计算总页数,确保向上取整"""
        return (self.total_items + self.items_per_page - 1) // self.items_per_page
 
    def get_page_data(self):
        """获取当前页的数据"""
        start_index = (self.page_number - 1) * self.items_per_page
        end_index = self.page_number * self.items_per_page
        return self.queryset[start_index:end_index]
 
    def get_pagination_html(self, base_url='?'):
        """
        生成分页 HTML
        :param base_url: 基础 URL,用于生成带参数的链接
        """
        half_range = self.visible_page_count // 2
        pagination_links = [f'<li><a href="{base_url}page=1">首页</a></li>']    # 首页
 
        if self.page_number > 1:
            pagination_links.append(f'<li><a href="{base_url}page={self.page_number - 1}" '
                                    f'aria-label="Previous"><span aria-hidden="true">«</span></a></li>')    # 上一页
 
        for i in range(1, self.total_pages + 1):
            if i == self.page_number:
                pagination_links.append(f'<li class="active"><a href="{base_url}page={i}">{i}</a></li>')    # 当前页
            elif abs(i - self.page_number) <= half_range:  
                pagination_links.append(f'<li><a href="{base_url}page={i}">{i}</a></li>')
 
        if self.page_number < self.total_pages:
            pagination_links.append(f'<li><a href="{base_url}page={self.page_number + 1}" '
                                    f'aria-label="Next"><span aria-hidden="true">»</span></a></li>')    # 下一页
 
        pagination_links.append(f'<li><a href="{base_url}page={self.total_pages}">尾页</a></li>')    # 尾页
 

实例化对象后,访问相关网页,浏览器报错提示没有 'items_per_page' 属性:

问题是我明明已经在初始化方法中确认了默认值  items_per_page=10 ,为什么还报错没有 'items_per_page' 属性?怪了。

问Chat GPT折腾了半天,问不出个所以然,问豆包倒是弄清楚了,调用内置方法的时候需要的属性未定义,一个简单的顺序问题。

豆包的回答如下:

在你提供的代码中,报错'CustomPaginator' object has no attribute 'items_per_page'看起来很奇怪,因为你确实在__init__方法里定义了items_per_page。经过仔细查看,问题出在_validate_page_number方法里:

def _validate_page_number(self, page_number):
    """
    校验并调整页码
    :param page_number: 用户输入的页码
    :return: 合法的页码
    """
    # 这里调用了 self._calculate_total_pages(),而此时 self.total_items 没问题,但 self.items_per_page 还未赋值
    return max(1, min(page_number, self._calculate_total_pages()))

_validate_page_number函数中,你调用了self._calculate_total_pages(),而这个函数依赖于self.items_per_page。但在__init__函数执行流程里,_validate_page_number是在self.items_per_page被赋值之前调用的,所以导致了这个属性在那一刻看起来没有被定义。

你可以把self.page_number = self._validate_page_number(page_number)这一行代码移到self.items_per_page = items_per_page之后,修改后的__init__方法如下:

def __init__ (self, queryset, page_number, items_per_page=10,
              visible_page_count=7):
    """
    初始化分页器
    :param queryset: 数据查询集
    :param page_number: 当前页码
    :param items_per_page: 每页显示的条目数
    :param visible_page_count: 分页导航中可见的页码数量
    """
    self.queryset = queryset
    self.total_items = self.queryset.count()    # 查询的数据(对象)个数

    self.items_per_page = items_per_page
    self.page_number = self._validate_page_number(page_number)

    self.visible_page_count = visible_page_count
    self.total_pages = self._calculate_total_pages()    # 分页个数

 这样就能保证items_per_page已经被正确赋值,再调用_validate_page_number就不会出错了。

 我还特意看了看Chat GPT的聊天记录,发现在第二次出现异常时,Chat GPT给出了正确的代码顺序,但是没有提出原因,看来国内的AI也挺牛的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值