Sayfalandırmayı Django sınıfı tabanlı genel ListView'lerle nasıl kullanabilirim?


183

Django 1.3 ile sayfalandırmayı nasıl kullanabilirim?

Belgeler bu konuda çok net değil.

  • Bana ne olacak views.py?

  • Şablonuma ne olacak?

  • URLconf dosyama ne gider?

Yanıtlar:


338

Geleneksel işlev tabanlı görünümlerle bulmak kolay olduğu için yeni sınıf tabanlı görünümlerle sayfalandırmayı kullanma hakkında bilgi istediğinizi düşünüyorum. Sadece paginate_bydeğişken ayarlayarak sayfalamayı etkinleştirmek için yeterli olduğunu buldum . See Sınıf temelli jenerik görünümleri .

Örneğin, Gözlerinde farklı views.py:

import models
from django.views.generic import ListView

class CarListView(ListView):
    model = models.Car      # shorthand for setting queryset = models.Car.objects.all()
    template_name = 'app/car_list.html'  # optional (the default is app_name/modelNameInLowerCase_list.html; which will look into your templates folder for that path and file)
    context_object_name = "car_list"    #default is object_list as well as model's_verbose_name_list and/or model's_verbose_name_plural_list, if defined in the model's inner Meta class
    paginate_by = 10  #and that's it !!

Şablonunuzda (In car_list.html), böyle bir sayfalama bölümü (: Biraz bağlam değişkenleri kullanılabilir olmasını içerebilir is_paginated, page_objve paginator).

{# .... **Normal content list, maybe a table** .... #}
{% if car_list %}
    <table id="cars">
        {% for car in car_list %}
            <tr>
                <td>{{ car.model }}</td>
                <td>{{ car.year }}</td>
                <td><a href="/car/{{ car.id }}/" class="see_detail">detail</a></td>
            </tr>
        {% endfor %}
    </table>
    {# .... **Now the pagination section** .... #}
    {% if is_paginated %}
        <div class="pagination">
            <span class="page-links">
                {% if page_obj.has_previous %}
                    <a href="/cars?page={{ page_obj.previous_page_number }}">previous</a>
                {% endif %}
                <span class="page-current">
                    Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
                </span>
                {% if page_obj.has_next %}
                    <a href="/cars?page={{ page_obj.next_page_number }}">next</a>
                {% endif %}
            </span>
        </div>
    {% endif %}
{% else %}
    <h3>My Cars</h3>
    <p>No cars found!!! :(</p>
{% endif %}
{# .... **More content, footer, etc.** .... #}

Görüntülenecek sayfa ?page=n, URL'ye basitçe eklenerek bir GET parametresi ile gösterilir .


1
Tamam, ama nasıl şablon bağlamak "car_list" nesne görmek?
gath

28
Bilginize, bunu doğrudan urls.py:url(r'^cars/$ ', ListView.as_view (model = Araba, paginate_by = 10)),
shawnwall'da

öğrendim ders: bir yöntem bulmak, tüm ata sınıflarını yeni sekmelerde açmak ve CTRL + F anahtar kelimeyi uzaklaştırmak. yani temel öğreticide var olduğunu bildiğimiz docs.djangoproject.com/tr/dev/ref/class-based-views/… adresinden tüm Atalar linklerini açın ve "pagi" için arama yapın
Ciro Santilli 郝海东 冠状 病 六四 事件法轮功

2
Bunu yapıyorum, ama bulduğum sorun, queryset içindeki nesneler üzerinde ekstra işlem yaptığımda, bunları veritabanındaki tüm sonuçlara uygular. Bu nedenle, 100 nesne döndüren ancak sayfa başına yalnızca on nesne gösteren bir sorgu için, fazla işlem 100 nesne üzerinde yapılır.
wobbily_col

32
Ben kodlanmış URL'ler gibi ile değiştirebilirsiniz yoktur: <a href="?page={{ page_obj.previous_page_number }}"> önceki </a>
dalore

42

varsayalım, app / models.py bir sınıf var FileExam(models.Model):

Uygulamanın / models.py

class FileExam(models.Model):
    myfile = models.FileField(upload_to='documents/%Y/%m/%d')
    date = models.DateTimeField(auto_now_add=True, blank=True)
    teacher_name = models.CharField(max_length=30)
    status = models.BooleanField(blank=True, default=False)

Uygulamanın / views.py

from app.models import FileExam
from django.core.paginator import Paginator
from django.core.paginator import EmptyPage
from django.core.paginator import PageNotAnInteger

class FileExamListView(ListView):
    model = FileExam
    template_name = "app/exam_list.html"
    paginate_by = 10
    
    def get_context_data(self, **kwargs):
        context = super(FileExamListView, self).get_context_data(**kwargs) 
        list_exam = FileExam.objects.all()
        paginator = Paginator(list_exam, self.paginate_by)

        page = self.request.GET.get('page')

        try:
            file_exams = paginator.page(page)
        except PageNotAnInteger:
            file_exams = paginator.page(1)
        except EmptyPage:
            file_exams = paginator.page(paginator.num_pages)
            
        context['list_exams'] = file_exams
        return context

Sadece çok az değişiklik get_context_datadjango belgelerinden ve katma sayfalandırma kod burada

Uygulamanın / templates / app / exam_list.html

normal içerik listesi

<table id="exam">
  {% for exam in list_exams %}
  <tr>
    <td>{{ exam.myfile }}</td>
    <td>{{ exam.date }}</td>
    <td>.....</td>
  </tr>
  {% endfor %}
</table>

paginate bölümü

{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
    <li>
        <span><a href="?page={{ page_obj.previous_page_number }}">Previous</a></span>
    </li>
{% endif %}
    <li class="">
        <span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.</span>
    </li>
{% if page_obj.has_next %}
    <li>
        <span><a href="?page={{ page_obj.next_page_number }}">Next</a></span>
    </li>
{% endif %}
</ul>
{% else %}
    <h3>Your File Exam</h3>
    <p>File not yet available</p>
{% endif %}

Uygulamanın / urls.py

urlpatterns = [
url(
    r'^$', views.FileExamListView.as_view(), name='file-exam-view'),
), 
... ]

1
Bu doğru görünmüyor: context = super(SoalListView, self).... Şunu mu demek istedin context = super(FileExamListView, self)...?
cezar

Evet doğru! Bu cevap Bay Yacin tarafından düzenlendi. Teşekkürler, Bay Yacin.
Yanwar Sky

1

Bunu yapmak için 2 yöntemimiz var.

Birincisi basit ve sadece sınıf alanını ayarlayın paginate_by. get_context_dataYöntemle ilgili bir şey yapmamıza gerek yok .

İkinci yöntem biraz karmaşıktır, ancak sayfalandırma hakkında daha fazla bilgi edinebilir ve karmaşık sayfalandırmayı veya birkaç sayfalandırmayı özelleştirebiliriz. Hadi onu görelim.

Üç adımda yapılabilir.

1.Override get_context_datayönteminizi geçersiz kılın View.

Pass page_keysve pagesböylece listeleri tekrarlayabilir ve sabit kodlamayı önleyebiliriz.

def get_context_data(self, *, object_list=None, **kwargs):
    context = super().get_context_data()
    df = pd.DataFrame(list(self.model.objects.all().values()))
    ipc = df.groupby('ip')['ip'].count().sort_values(ascending=False)
    urlc = df.groupby('url')['url'].count().sort_values(ascending=False).to_dict()

    ipc = tuple(ipc.to_dict().items())
    urlc = tuple(urlc.items())

    pages = []
    page_keys = ['page1', 'page2']
    for obj, name in zip([urlc, ipc], page_keys):
        paginator = Paginator(obj, 20)
        page = self.request.GET.get(name)
        page_ipc = obj
        try:
            page_ipc = paginator.page(page)
        except PageNotAnInteger:
            page_ipc = paginator.page(1)
        except EmptyPage:
            page_ipc = paginator.page(paginator.num_pages)
        pages.append(page_ipc)

    context['data'] = zip(pages, page_keys)
    return context

2. alt özelleştirin template.

Sayfalama listesinde yineleme yapabilmemiz için bazı değişkenler tanımlarız.

pagination.html

    {% if is_paginated %}
        <ul class="pagination">
        {% if page_obj.has_previous %}
            <li>
            <span><a href="?{{ pname }}={{ page_obj.previous_page_number }}">Previous</a></span>
            </li>
        {% endif %}
        <li class="">
            <span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.</span>
        </li>
        {% if page_obj.has_next %}
            <li>
            <span><a href="?{{ pname }}={{ page_obj.next_page_number }}">Next</a></span>
            </li>
        {% endif %}
        </ul>
    {% else %}
        <h3>Your File Exam</h3>
        <p>File not yet available</p>
    {% endif %}

3. dış özelleştirin template.

index.html

{% for foo,name in data %}
    <div class="col-md-3 table-responsive">

            {% for k,v in foo %}
                <tr>
                    <th>{{ forloop.counter }}</th>
                    <td>{{ k }}</td>
                    <td>{{ v }}</td>
                </tr>
            {% endfor %}

        {% include 'pagination.html' with pname=name  page_obj=foo %}
    </div>
{% endfor %}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.