django admin中的内联模型分页器

mkshixfv  于 2023-06-25  发布在  Go
关注(0)|答案(6)|浏览(146)

我有一个简单的django模型,由一个传感器和特定传感器的值组成。每个日射强度计的值的数量很高(> 30 k)。是否有可能以某种方式分页PyranometerValues的一个特定的一天或generell应用一个分页到管理内联视图?

class Pyranometer(models.Model):
     name = models.CharField(max_length=75)                                                                             

class PyranometerValues(models.Model):                                                                                 
    timestamp = models.DateTimeField()
    value = models.DecimalField(max_digits=10,decimal_places=6)                                                        
    sensor = models.ForeignKey('Pyranometer')
rm5edbpk

rm5edbpk1#

如果有人需要这样做,我在a django-suit问题的注解中发现了一个分页TabularInline子类的很好的(尽管被描述为“相当古怪”)实现。
对于Django 1.6,它需要修改模板并将这个PaginationInline类子类化:

from django.contrib import admin
from django.contrib.admin.views.main import ChangeList
from django.core.paginator import EmptyPage, InvalidPage, Paginator

class InlineChangeList(object):
    can_show_all = True
    multi_page = True
    get_query_string = ChangeList.__dict__['get_query_string']

    def __init__(self, request, page_num, paginator):
        self.show_all = 'all' in request.GET
        self.page_num = page_num
        self.paginator = paginator
        self.result_count = paginator.count
        self.params = dict(request.GET.items())

class PaginationInline(admin.TabularInline):
    template = 'admin/edit_inline/tabular_paginated.html'
    per_page = 20

    def get_formset(self, request, obj=None, **kwargs):
        formset_class = super(PaginationInline, self).get_formset(
            request, obj, **kwargs)
        class PaginationFormSet(formset_class):
            def __init__(self, *args, **kwargs):
                super(PaginationFormSet, self).__init__(*args, **kwargs)

                qs = self.queryset
                paginator = Paginator(qs, self.per_page)
                try:
                    page_num = int(request.GET.get('p', '0'))
                except ValueError:
                    page_num = 0

                try:
                    page = paginator.page(page_num + 1)
                except (EmptyPage, InvalidPage):
                    page = paginator.page(paginator.num_pages)

                self.cl = InlineChangeList(request, page_num, paginator)
                self.paginator = paginator

                if self.cl.show_all:
                    self._queryset = qs
                else:
                    self._queryset = page.object_list

        PaginationFormSet.per_page = self.per_page
        return PaginationFormSet
x6yk4ghg

x6yk4ghg2#

对于任何版本的Django,请按照以下步骤操作:

1.访问此文件:python3.7/site-packages/django/contrib/admin/templates/admin/edit_inline/tabular.html将其复制到您的app/templates/admin/edit_inline/anyname.html
</table></fieldset>标签之间添加anyname.html

<style>
    .dark {
      /*background-color: #417690;*/
      background-color: #FFFFFF;
      border: none;
      color: #666;
      padding: 5px 10px;
      text-align: center;
      text-decoration: none;
      display: inline-block;
      font-size: 12px;
      margin: 4px 2px;
      cursor: pointer;
    }
    .light {
      background-color: #008CBA;
      border: none;
      color: white;
      padding: 5px 10px;
      text-align: center;
      text-decoration: none;
      display: inline-block;
      font-size: 12px;
      margin: 4px 2px;
      cursor: pointer;
    }

  </style>
   <div>
   {% with inline_admin_formset.formset.page as page_obj %}
    <p class="paginator">
      {% if page_obj.previous_page_number > 1 %}
        <a href="?page={{ page_obj.previous_page_number|add:'-1' }}">{% trans 'previous' %}</a>
      {% endif %}

      {% if page_obj.number|add:"-5" > 0 %}
        <a href="?page=0">1</a>
      {% endif %}

      {% if page_obj.number|add:"-5" > 1 %}
        <span>&hellip;</span>
      {% endif %}

      {% for page_num in page_obj.paginator.page_range %}
        {% if page_obj.number == page_num %}
          <span class="dark">{{ page_num|add:"-1" }}</span>
        {% else %}
          {% if page_num > page_obj.number|add:"-5" and page_num < page_obj.number|add:"5" %}
            <a class="light" style="color:white" href="?page={{ page_num|add:'-1' }}">{{ page_num|add:"-1" }}</a>
          {% endif %}
        {% endif %}
      {% endfor %}

      {% if page_obj.number|add:"5" < page_obj.paginator.num_pages %}
        <span>&hellip;</span>
      {% endif %}

      {% if page_obj.number|add:"4" < page_obj.paginator.num_pages %}
        <a href="?page={{ page_obj.paginator.num_pages }}">{{ page_obj.paginator.num_pages }}</a>
      {% endif %}

      {% if page_obj.next_page_number < page_obj.paginator.num_pages|add:'1' %}
        <a href="?page={{ page_obj.next_page_number|add:'-1' }}">{% trans 'next' %}</a>
      {% endif %}
      <span class='dark'>{{ page_obj.paginator.count }} Queries</span>
    </p>
  {% endwith %}
  </div>

2.进入您的admin.py文件:

from django.contrib.admin.views.main import ChangeList
from django.core.paginator import EmptyPage, InvalidPage, Paginator

class InlineChangeList(object):
    can_show_all = True
    multi_page = True
    get_query_string = ChangeList.__dict__['get_query_string']

    def __init__(self, request, page_num, paginator):
        self.show_all = 'all' in request.GET
        self.page_num = page_num
        self.paginator = paginator
        self.result_count = paginator.count
        self.params = dict(request.GET.items())

class MyInline(admin.TabularInline):
    per_page = 10
    template = 'admin/edit_inline/anyname.html'
    model = Mymodel
    extra = 0
    can_delete = False

    def get_formset(self, request, obj=None, **kwargs):
        formset_class = super(MyInline, self).get_formset(
            request, obj, **kwargs)
        class PaginationFormSet(formset_class):
            def __init__(self, *args, **kwargs):
                super(PaginationFormSet, self).__init__(*args, **kwargs)

                qs = self.queryset
                paginator = Paginator(qs, self.per_page)
                try:
                    page_num = int(request.GET.get('page', ['0'])[0])
                except ValueError:
                    page_num = 0

                try:
                    page = paginator.page(page_num + 1)
                except (EmptyPage, InvalidPage):
                    page = paginator.page(paginator.num_pages)

                self.page = page
                self.cl = InlineChangeList(request, page_num, paginator)
                self.paginator = paginator

                if self.cl.show_all:
                    self._queryset = qs
                else:
                    self._queryset = page.object_list

        PaginationFormSet.per_page = self.per_page
        return PaginationFormSet
uttx8gqw

uttx8gqw3#

是否检查了raw_id_fields属性?我想你可能会觉得有用。

xyhw6mcr

xyhw6mcr4#

由于django-admin主要是一个模板的问题(只需要将模板重新定义到一些django-admin-tools部分),我有一个想法。
是Django的分页模块,如linaro-django-pagination或endless-pagination,它们提供模板标签来对任何给定的可迭代内容进行分页。
如果您可以找到负责显示内联模型的模板,您可以将其复制到您的项目中,然后尝试向其添加{% load pagination_tags %}并对内联进行分页。
我没有测试过它,也没有仔细考虑过它,但除了验证,我看不出它怎么会失败。测试并告诉我们。

w1e3prcc

w1e3prcc5#

那么,动态生成的过滤器可能会有所帮助:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter
此外,管理员有一个很好的GET类型查询,如:
localhost:8000/admin/pyranometervalues/?值=10.0
您可以将日期指定为:
admin/日射强度计值/?timestamp_year=2011&timestamp_month=10&timestamp__day=13
等等不幸的是,我不知道一个更短的方式,使这个查询在管理。有什么想法吗?:)
编辑:这只是为了缩小你的查询范围,与分页无关;)

scyqe7ek

scyqe7ek6#

在我的例子中,django-admin-inline-paginator分页内联是有效的。
我有一个项目与900相关的同类项目,必须显示为内联。在使用这个包之前,我得到了502,因为nginx在uwsgi能够创建响应之前超时。使用这个软件包帮助我大大减少了响应时间,虽然我相信我仍然会有很多交通问题
仅供参考,我从uwsgi得到的错误是:

DAMN ! worker 3 (pid: 19) died, killed by signal 9 :( trying respawn ...
Respawned uWSGI worker 3 (new pid: 22)
SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request <> (ip <>) !!!
uwsgi_response_write_body_do(): Broken pipe [core/writer.c line 341] during GET <> (<>)
OSError: write error

相关问题