Estoy aprendiendo Django. Actualmente construyo mi proyecto de blog. Quiero agregar la función para filtrar las publicaciones por fecha (puede elegir una fecha específica del cuadro combinado y hacer clic en el botón "filtro" y luego en la página principal mostrará solo las publicaciones que se crearon en esta fecha). Como todavía soy nuevo en django, me cuesta cómo manejarlo.

Mi pregunta es cómo crear una funcionalidad que extraiga la fecha de envío del cuadro combinado y la pase a la vista donde haré el filtrado apropiado en el método get_queryset. A continuación publico mi código:

Parte de mi archivo .html donde construyo el cuadro combinado:

<p class='text-muted'>Choose date from the list below.</p>
<form method="GET">
    <select name="date_filter">
        <option>-----------------</option>
        {% for post in posts %}
            <option>{{ post.date_posted }}</option>
        {% endfor %}
    </select>
    <button type="submit" class="btn btn-info btn-sm mt-1 mb-1">Filter</button>
</form>

También me gustaría que cada fecha sea única y se muestre solo una vez. Actualmente, cada fecha se muestra tantas veces como se crearon tantas publicaciones ese día porque DateTimeField en mi modelo también almacena la hora de creación de publicaciones.

Vista de la página principal donde se muestran las publicaciones: en mi archivo views.py:

class PostListView(ListView):
    model = Post
    template_name = "blog_app/home.html" 
    context_object_name = 'posts' 
    ordering = ['-date_posted'] 

    # I believe here should be something which fetch choice from combo box and asign it to the 
    # date_from_combo_box variable. Please, correct me if I'm wrong.

    def get_queryset(self):
        # Here I will decide what posts are to be displayed based on the selection made in the combo box
        if self.date_posted == date_from_combo_box:
            return Post.objects.filter(date_posted=date_from_combo_box)

Mi archivo models.py:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('post-detail', kwargs={'pk': self.pk})


class Comment(models.Model):
    comm_content = models.TextField()
    add_date = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)

    def __str__(self):
        return f"Comment of post {self.post} posted at {self.add_date}."

    def get_absolute_url(self):
        return reverse('post-detail', kwargs={'pk': self.post.pk})

Gracias por cualquier sugerencia y consejo.

The main page where is combo box and posts are displayed.

0
Tomasz 24 dic. 2019 a las 14:53

2 respuestas

La mejor respuesta

Para obtener una fecha única de su tabla de publicación para el menú desplegable, cambie su consulta a

Post.objects.dates('date_posted', 'day').distinct()

Cambia tu html

<p class='text-muted'>Choose date from the list below.</p>
<form action="url_to_list_view" method="GET">
    <select name="date_filter">
        <option>-----------------</option>
        {% for post in posts %}
            <option>{{ post.date_posted }}</option>
        {% endfor %}
    </select>
    <button type="submit" class="btn btn-info btn-sm mt-1 mb-1">Filter</button>
</form>

Su vista de lista se verá así.

class PostListView(ListView):
    model = Post
    template_name = "blog_app/home.html" 
    context_object_name = 'posts' 
    ordering = ['-date_posted'] 

    def get_queryset(self):
        search = self.request.GET.get('date_filter', None)
        if search is not None:
            return Post.objects.filter(date_posted__date=search)
        else:
            return Post.objects.all()
0
Sachin Singh 24 dic. 2019 a las 13:05

Podrías usar algo como esto, Model.objects.filter(date_attribute__month=month, date_attribute__day=day)

O para un rango que puedes usar

Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])

Créditos

0
Sahil 24 dic. 2019 a las 11:59