Esta es el arreglo más correcta que encomtrarás compartir, pero estúdiala detenidamente y analiza si se adapta a tu trabajo.
Solución:
Esto funcionó para mí:
en mi plantilla en lugar de usar esto
i
Yo escribí esto:
% if 'whatever_parameter_you_use_to_filter' in request.get_full_path %
% else %
i
% endif %
Espero que ayude 🙂
Para usar Django Filter y paginar el resultado filtrado, puede hacer lo siguiente:
-
Cree una clase de filtro para su modelo:
Sobre
my_project/my_app/filters.py
:import django_filters class MyModelFilter(django_filters.FilterSet): class Meta: model = MyModel # Declare all your model fields by which you will filter # your queryset here: fields = ['field_1', 'field_2', ...]
-
Cada
FilterSet
el objeto tiene un.qs
propiedad que contiene el conjunto de consultas filtradas e incluso puede anularlo si lo desea. -
Paginaremos el
.qs
propiedad de nuestroMyModelFilter
:Sobre
my_project/my_app/views.py
:from . import filters from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def my_view(request): # BTW you do not need .all() after a .filter() # local_url.objects.filter(global_url__id=1) will do filtered_qs = filters.MyModelFilter( request.GET, queryset=MyModel.objects.all() ).qs paginator = Paginator(filtered_qs, YOUR_PAGE_SIZE) page = request.GET.get('page') try: response = paginator.page(page) except PageNotAnInteger: response = paginator.page(1) except EmptyPage: response = paginator.page(paginator.num_pages) return render( request, 'your_template.html', 'response': response )
¡Y ahí lo tienes!
PS_1: En mi experiencia, el filtro Django “juega” mejor con Django Rest Framework.
PS_2: Si está a punto de utilizar DRF, he escrito un ejemplo sobre cómo usar la paginación en una vista basada en funciones que puede combinar fácilmente con una FilterSet
:
@api_view(['GET',])
def my_function_based_list_view(request):
paginator = PageNumberPagination()
filtered_set = filters.MyModelFilter(
request.GET,
queryset=MyModel.objects.all()
).qs
context = paginator.paginate_queryset(filtered_set, request)
serializer = MyModelSerializer(context, many=True)
return paginator.get_paginated_response(serializer.data)
La parte más importante aquí es la cómo construyes tus URL en la plantilla.
probablemente tienes
% if pages.has_previous %
Prev
% endif %
lo cual está perfectamente bien si lo está utilizando solo para cambiar entre los resultados paginados iniciales.
Pero la parte complicada es cuando usas el django-fitler
filtros, la cadena de consulta (esa parte después de la ‘?’) se vuelve totalmente nuevo key-valores pares, sin tener en cuenta su ?page=2
o similar.
Por lo tanto, para que la paginación funcione con resultados filtrados, cuando haga clic en el botón “Siguiente” o “Anterior”, entre los key-valores de django-fitler
también necesitas pasar el &page=5
como pareja.
Como mencionó @stathoula, debe verificar si al menos uno de sus campos de filtro ya está presente en la cadena de consulta. Si es así, entonces necesita usar el ya presente key-pares de valores, seguidos del nuevo &page=3
par.
Parece muy simple, pero tuve que hacer un pequeño truco para no repetir el &page=1
una y otra vez dentro de la cadena de consulta a medida que un usuario hace clic en las flechas.
En mi caso, tengo ‘título’ como filtro, por lo que necesito verificar si ya está presente allí.
Aquí hay un fragmento de lo que hice que funcionara perfectamente bien para mi proyecto.
templates / pagination.html
% with request.get_full_path as querystring %
% endwith %
Aquí está la vista, por si acaso:
app / views.py
def index(request):
condo_list = Condo.objects.all().order_by('-timestamp_created')
condo_filter = CondoFilter(request.GET, queryset=condo_list)
paginator = Paginator(condo_filter.qs, MAX_CONDOS_PER_PAGE)
page = request.GET.get('page')
try:
condos = paginator.page(page)
except PageNotAnInteger:
condos = paginator.page(1)
except EmptyPage:
condos = paginator.page(paginator.num_pages)
return render(request, 'app/index.html',
'title': 'Home',
'condos': condos,
'page': page,
'condo_filter': condo_filter,
)
Aquí hay un ejemplo de trabajo:
valoraciones y reseñas
Si guardas alguna indecisión o disposición de modernizar nuestro noticia eres capaz de dejar una referencia y con deseo lo estudiaremos.