0

I have a class jourListView(ListView). I want to input date in my html template and then retrieve the date to make a filter. My class jourListView(ListView) refers to two linked tables. I am stuck at level. How to make my code functional?

here are my models, views and template.

class jour(models.Model):
    user = models.ForeignKey(User,on_delete=models.CASCADE, related_name='jour')
    date = models.DateField(blank=True, null=True)
    commentaire = models.CharField(max_length=500, blank=True, null=True)
    class Meta:
        managed = False
        db_table = 'jour'
        unique_together = (('id'),)
        verbose_name = 'JOUR'
        verbose_name_plural = 'JOUR'

    id = models.AutoField(primary_key=True)

    def get_absolute_url(self):
        return reverse("jour_detail",kwargs={'pk':self.pk})

    def __str__(self):
        return str(self.date) ##


class activite(models.Model):
    jour = models.ForeignKey('blog.jour',on_delete=models.CASCADE, related_name='jour' )
    name= models.CharField(max_length=500, blank=True, null=True)
    class Meta:
        managed = False
        db_table = 'activite'
        unique_together = (('id'),)
        verbose_name = 'ACTIVITÉ'
        verbose_name_plural = 'ACTIVITÉ'

    id = models.AutoField(primary_key=True)

    def __str__(self):
        return self.type

    def get_absolute_url(self):
        return reverse("jour_list")

My view:

class jourListView(ListView):
    model = jour
    def get_context_data(self, **kwargs):
        if request.method == 'POST':
            date_insert = request.POST.get('date_ref')
            context = super(jourListView, self).get_context_data(**kwargs)
            context['count'] = self.get_queryset().count()
            return context

    def get_queryset(self):
        return jour.objects.filter(date__lte=timezone.now()).filter(user=self.request.user).filter(date__in=date_insert)

My html template:

{% if user.is_authenticated %}

  <div class="container text-center">
      <form class="form-signin" id="login_form" method="post" action="/blog/list/">
        {% csrf_token %}

        <br>
        <input type="date" name="date_ref" class="form-control" placeholder="SAISIE DATE " value="" required autofocus>
        <br>
        <button class="btn btn-lg btn-primary btn-block" type="submit">OK</button>
      </form>
  </div>

    <div class="centerstage">

        {% for jour in jour_list %}
            <div class="post">
              <p class='postcontent' ><strong>Date:</strong> {{ jour.date }}</p>
              <p class='postcontent' ><strong>Commentaire:</strong> {{ jour.commentaire }}</p>
              <a class="btn btn-primary" href="{% url 'jour_edit' pk=jour.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
              <h1><a href="{% url 'jour_detail' pk=jour.pk %}">Détails activités</a></h1>
            </div>
        -----------------
        {% endfor %}

    </div>

{% endif %}

I changed my view but it does not work.

class jourListView(ListView):
model = jour
template_name = "blog/list.html"
def get_context_data(self, **kwargs):
    if request.method == 'POST':
        date_insert = request.POST.get('date_ref')
        context = super(jourListView, self).get_context_data(**kwargs)
        context['count'] = self.get_queryset().count()
        return context

def get_queryset(self):
    queryset = jour.objects.filter(date__lte=timezone.now()).filter(user=self.request.user)
    date_insert = request.POST.get('date_ref')
    if date_insert:
        queryset = queryset.filter(date=date_insert)
    return queryset

In addition I have another error: NameError at /blog/list/ name 'request' is not defined

Request Method: GET

Request URL: http://127.0.0.1:8000/blog/list/

Django Version: 2.0.2

Exception Type: NameError

Exception Value: name 'request' is not defined

Bak
  • 411
  • 1
  • 5
  • 19

2 Answers2

0

You need to define date_insert inside the get_queryset method before you use it. For example:

class jourListView(ListView):
    model = jour

    def get_context_data(self, **kwargs):
        if self.request.method == 'POST':
            date_insert = self.request.POST.get('date_ref')
            context = super(jourListView, self).get_context_data(**kwargs)
            context['count'] = self.get_queryset().count()
            return context

    def get_queryset(self):
        queryset = jour.objects.filter(date__lte=timezone.now()).filter(user=self.request.user)
        date_insert = self.request.POST.get('date_ref')
        if date_insert:
            queryset = queryset.filter(date=date_insert)
        return queryset

Once that's working, you may want to consider some further improvements

  • Renaming the model to Jour to match the Django style
  • Make sure you return a context in get_context_data for GET requests as well as POST requests.
  • Using LoginRequiredMixin to make sure that only logged in users can access the view
  • Adding checks to handle the case where date_insert isn't a valid date string.
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • I changed my view but it does not work. In addition I have another error: NameError at /blog/list/ name 'request' is not defined Request Method: GET Request URL: http://127.0.0.1:8000/blog/list/ Django Version: 2.0.2 Exception Type: NameError Exception Value: name 'request' is not defined – Bak Feb 22 '18 at 12:33
  • Use `self.request` in class based views methods, not `request`. The approach in my answer should work, but I can't help you debug every issue in your code. – Alasdair Feb 22 '18 at 12:42
  • I did not succeed . Can you send me an example please? I want to insert a value in my template, then retrieve this value to make a filter in my Listview. Thank you – Bak Feb 22 '18 at 16:13
  • The code above already shows how to retrieve `date_ref` from the POST data and use it to filter the queryset. – Alasdair Feb 22 '18 at 16:18
0

I found the solution to my problem. Here is the result:

I was inspired by the example in this link: Django: Search form in Class Based ListView

My view:

class jourListView(ListView):
    model = jour
    template_name = "blog/list.html"
    def get_context_data(self, **kwargs):
        context = super(jourListView, self).get_context_data(**kwargs)
        # FILTER BY CURRENT MONTH, USER
        filter_ = jour.objects.filter(date__lte=timezone.now()).filter(user_id=self.request.user).order_by('-date')
        if self.request.GET.get('date_ref'):
            date_insert  = self.request.GET.get('date_ref')
            filter_ = filter_.filter(date=date_insert) 
        context['jourListView'] = filter_
        return context

My template (blog/list.html):

{% extends 'blog/base.html' %}
{% block content %}
    {% if user.is_authenticated %}
            <form class="navbar-form navbar-right"  action="." method="get">
                {{ form.as_p }}
                <input id="date_ref" name="date_ref" type="date" placeholder="Localizar..." class="form-control">
                <button type="submit" class="btn btn-success form-control"><span class="glyphicon glyphicon-search"></span></button>
            </form>

            {% if jourListView %}
                {% for select_value in jourListView %}
                    <div class="post">
                      <p class='postcontent' ><strong>Date:</strong> {{ select_value.date}}</p>
                      <p class='postcontent' ><strong>User ID:</strong> {{ select_value.user_id}}</p>
                      <p class='postcontent' ><strong>Status:</strong> {{ select_value.status}}</p>
                    </div>
                -----------------
                {% endfor %}
            {% endif %}
    {% endif %}
{% endblock %}
Bak
  • 411
  • 1
  • 5
  • 19