Querysets "lost" when I render them in the template - django

I was stucked the last two days with this problem. First part of the code:
viewa.py
def A_dashboard(request):
user = User.objects.get(id=request.user.id)
users = User.objects.all()
return render_to_response('dashboard.html', {"user": user, "users": users} , context_instance=RequestContext(request))
The dashboard will be different depending of one property of the user.
dashboard.html
{% extends "index.html" %}
{% load staticfiles %}
{% block content %}
{% if user.is_A %}
{% include "dashboards/A_dashboard.html" %}
{% endif %}
{% if user.is_B %}
{% include "dashboards/B_dashboard.html" %}
{% endif %}
{% endblock content %}
The concrete dashboard to the A user.
dashboards/A_dashboard.html
{% load staticfiles %}
<div class="offrow rowpadding dashboard-info">
<div class="container">
<div class="row">
<div class="col-lg-7">
<div class="row">
{{user}}
{{users}}
{% for user_ in users %}
<p>{{user_}}</p>
{% endfor %}
</div>
</div>
<div class="col-lg-5">
<div class="row">
<div class="col-md-12">
{% include 'calendar.html' %}
</div>
</div>
</div>
</div>
</div>
Right Now Im logged in as an A user. In the view I check the class to check that everything is ok. Its of class <class 'django.db.models.query.QuerySet'>
However, when I try to iterate the list in the template, it doesn't exist.
Can you imagine whats happening?
Regards.

it is strange that objects don't exist.
User.objects.all() is queryset, so in template users is a queryset.
user is a user object, it has some attributes, such as username , email and so on.
for user_ in users you get every user object(user_) similar to user above
so try this
<div class="row">
nameļ¼š {{ user.username }}
{% for user_ in users %}
<p>name: {{ user_.username }}</p>
{% endfor %}
</div>
{{user.username}} and {{ user.username }} are the same, spaces just for looking elegant

Related

Show / hide input field or div based on RadioField choice using Flask wtf_form

I am trying to build website using Flask, and can't find solution to one problem. I am trying to hide or show input field, based on RadioFeild choice. Also, if input field showing, it have to be required. I actually have everything working, besides knowing what RadioField choice was selected. I can see the form when loading page on 127.0.0.1:5000 and I can see RadioField with 2 choices: Yes and No, but when I click on yes, there are no changes, hidden input field is still not showing. Please, help!
app.py
class MyClass(FlaskForm):
my_field = RadioField("bla-bla-bla", choices=[('Yes', 'Yes'), ('No', 'No')], validators [InputRequired()])
#app.route("/some_page")
def some_page():
form = MyClass()
return render_template("some_page.html", form=form)
_render_field.html
{% macro render_radio_field(field) %}
<div class="form__item">
<label class="form__label">{{field.label.text }}</label>
<div class="form-group">
{{ field(class_='form__input', **kwargs)|safe }}
{% for subfield in field %}
<div class="form__item">
<label>
{{ subfield }}
{{ subfield.label.text }}
</label>
</div>
{% endfor %}
</div>
</div>
{% endmacro %}
some_page.html
{% from "_render_field.html" import render_field, render_radio_field %}
{% extends "layout.html" %}
{% block title %}My Title{% endblock %}
{% block content %}
<div style="width:600px; margin:0 auto;">
<h3>Some Text</h3>
<form class="form" action="{{url_for('some_page')}}" method="POST">
{% from "_render_field.html" import render_field, render_radio_field %}
{{ form.csrf_token }}
{{ render_field(my_field, title="", style="list-style:none") }}
{% if form.my_field.option == "Yes" %}
{{ render_field(form.some_other_StringField, placeholder="Please explain:", title="") }}
{% endif %}
<input type="submit" name="" value="login" class="form__btn">
</form>
</div>
{% endblock %}

How to fix pagination after making a search for specific data in django_tables2

In my project I am using with success django_tables2 in order to achieve server side processing.
The only thing that I do not know how to handle is that after searching, for example by name in a template rendering clients for my application, the search despite the fact that gives some returned results based on the name, it is not working properly if the result records are spread in more than one page based on my pagination.
In other words, when I am clicking the 2 (second page of my returned results), the app is showing all the pages concerning the clients 1 2 3 ...45 next (as i want to reach the /clients/ url, and not the 1 2 next structure for only the custom search data.
This happening also when I am clicking the next and previous buttons.
One easy solution It could be to increase my pagination limit in order to show all the possible results in one page, but this solution is not proper for big result sets.
Is there any solution to avoid loading and showing all the pages in the search bar and only keeping the results of my custom search?
Below is my snippets.
url.py
url(r'^clients/$', views.client_list, name='client_list'),
models.py
class Client(models.Model):
name = models.CharField(max_length=50, verbose_name="Name")
surname = models.CharField(max_length=50, verbose_name="Surname")
activity = models.IntegerField(choices=ACTIVITY_OPTIONS, null=True,default=ACTIVE)
views.py
def client_list(request, template_name='clients/client_list.html'):
if request.method == 'POST':
search_string = request.POST['search_client']
current_client=Client.objects.filter(Q(activity=1) & Q(name=search_string)| Q(surname=search_string))
single_table=ClientTable(current_client)
RequestConfig(request).configure(single_table)
return render(request,template_name, {'single_table': single_table})
else:
clients=Client.objects.filter(activity=1)
table = ClientTable(clients)
RequestConfig(request).configure(table)
return render(request,template_name, {'table': table})
tables.py
class ClientTable(tables.Table):
class Meta:
#define the model
model = Client
exclude=('..')
template_name = 'django_tables2/bootstrap.html'
sequence = ("surname", "name",)
template
{% extends 'base.html' %}
{% load has_group %}
{% load render_table from django_tables2 %}
{% load bootstrap3 %}
{% load static %}
{% load staticfiles %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-12">
<form class="well" method="post" action="">
{% csrf_token %}
Client Search:<br>
<input type="text" class="form-control" id="search" name="search_client">
<br>
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "like" %} Submit
</button>
{% endbuttons %}
</form>
{% if single_table %}
{% render_table single_table %}
{% endif %}
{% if table %}
{% render_table table %}
{% endif %}
</div>
</div>
</div>
{% endblock %}
Finally after searching I found a solution.
Django filters https://django-filter.readthedocs.io/en/master/index.html can be used in situations like this one.
The steps I followed are:
1) import the 'django_filters', to settings.py
2) Define the filters.py
import django_filters
from .models import Patient
class ClientFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = Client
fields = ['id','name','surname']
3) Modify the views.py
class FilteredClientListView(SingleTableMixin, FilterView):
table_class = ClientTable
model = Client
template_name ='clients/client_list2.html'
filterset_class = ClientFilter
4) Modify urls.py accordingly since I used class based function
url(r'^clients2/$', views.FilteredClientListView.as_view(), name='client_list2'),
5) Modify my template
{% extends 'base.html' %}
{% load has_group %}
{% load render_table from django_tables2 %}
{% load bootstrap3 %}
{% load static %}
{% load staticfiles %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-12">
<form class="well" method="post" action="">
{% csrf_token %}
Client Search:<br>
<input type="text" class="form-control" id="search" name="search_client">
<br>
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "like" %} Submit
</button>
{% endbuttons %}
</form>
{% if filter %}
<form action="" method="get" class="form form-inline">
{% bootstrap_form filter.form layout='inline' %}
{% bootstrap_button 'filter' %}
</form>
{% endif %}
{% if single_table %}
{% render_table single_table %}
{% endif %}
{% if table %}
{% render_table table %}
{% endif %}
</div>
</div>
</div>
{% endblock %}
P.S : importing in the views.py the appropriate tables and filters

Django: the information is not processed for a given condition if

Template tag {% if %} {% endif %} does't work correctly. I need to make the search results on the page appear only after the search query. But for some reason, when the page loads, all existing content appears at once. But after get request filter works correctly.
views.py
def search(request):
place_list = Places.objects.all()
place_filter = PlaceFilter(request.GET, queryset=place_list)
return render(request, 'search/user_list.html', {'filter': place_filter})
html
{% if filter.qs %}
<div class="row">
{% for obj in filter.qs %}
<div class="col-md-3 admin__block">
<div class="cover__wrapper">
<img src="{{ obj.main_photo.url }}" alt="">
<span>#</span>{{ obj.name }}
<p>{{ obj.description }}</p>
</div>
</div>
{% endfor %}
</div>
{% endif %}
filters.py
class PlaceFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='icontains', widget=forms.TextInput(attrs={
'placeholder': 'Search place', 'class': 'input__search'}))
class Meta:
model = Places
fields = ['name']
FilterSet's qs property returns filterset's queryset. So it's always True.
You can use request.GET in template to check if GET contains any request data and render only filtered data:
{% if request.GET %}
<div class="row">
{% for obj in filter.qs %}
<div class="col-md-3 admin__block">
<div class="cover__wrapper">
<img src="{{ obj.main_photo.url }}" alt="">
<span>#</span>{{ obj.name }}
<p>{{ obj.description }}</p>
</div>
</div>
{% endfor %}
</div>
{% endif %}

django tables how to detect if table is empty

I am new to django and web development and based on examples and help on SO, I have pieced together something which takes a model and renders it in a django-table. My template code is basically as follows:
{% block content %}
{% load static %}
{% load render_table from django_tables2 %}
<div class="function-page">
<div class="table-form">
<div class="function-container">
{% render_table reviews %}
</div>
</div>
</div>
{% endblock %}
The view is as follows:
#login_required(login_url="login/")
def review(request):
table = DummyTable(DummyModel.objects.all())
form = DummyForm()
RequestConfig(request, paginate={"per_page": 10}).configure(table)
return render(request, 'review.html', {'reviews': table, 'DummyForm': form})
This works fine. However, what I would like to do is show a message to the user saying that there are no records when the database table is empty. In the current setting, it shows an empty table with the columns which is probably not the best from a usability point of view.
There are two options. Either you set empty_text inside class Meta
class Reviews(tables.Table):
class Meta:
empty_text = _("There are no reviews yet")
Or you can check it inside the template and avoid rendering table this way
{% if reviews_table.data.list %}
{% render_table reviews_table %}
{% else %}
<h1>There are no reviews yet</h1>
{% endif %}
Probably the easiest way is in your template. Assuming your variable that's empty is called reviews:
{% block content %}
{% load static %}
{% if reviews %}
{% load render_table from django_tables2 %}
<div class="function-page">
<div class="table-form">
<div class="function-container">
{% render_table reviews %}
</div>
</div>
</div>
{% else %}
<span> Whatever holding response/error message you want. </span>
{% endif %}
{% endblock %}
Per this this answer, for example, using {% if variable %} against a valid but empty variable, it generally evaluates to False, letting you use the {% if reviews %}.
However, if you need a really bulletproof check, you can do {{ value|default:"nothing" }} - from here.
You could also do it in your views, and pass an error message back to the template using the standard Messages framework included in Django:
from django.contrib import messages
messages.add_message(request, messages.INFO, "No reviews found, I'm afraid!.")
You need to include something like this in your templates to use messages:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
Or you could do both! :)
test against table.paginated_rows it will be empty and evaluated to False when the table have no data.
they use this in django_tables2/templates/django_tables2/bootstrap.html:~26 template:
{% for row in table.paginated_rows %}
...
{% empty %}
... {{ table.empty_text }}
{% endfor %}
Do this:
{% if reviews %}
<div class="function-page">
<div class="table-form">
<div class="function-container">
{% render_table reviews %}
</div>
</div>
</div>
{% else %}
<div>
<p> Message to use </p>
</div>
{% endif %}
Milano answer worked to me, but removing ".list" from the if conditional:
{% if reviews_table.data.list %}
{% render_table reviews_table %}
{% else %}
<h1>There are no reviews yet</h1>
{% endif %}

Django authentication acting weird. Working "some times", not always

I'm having some trouble with Django's authentication system. I've managed to set up a login page, logout page and a basic profile page. Now I'm trying to restrict different areas on the site to only authenticated users. It works on some templates, and not on others.
The weirdest, maybe, is that it works/not works in the same template.
This is base.html:
<div id="account">
{% if user.is_authenticated %}
Hello, {{ user.username }}! | Log out
{% else %}
Log in
or
Sign up
{% endif %}
</div>
<div id="sidebar">
{% if user.is_authenticated %}
<h3 id="plus" style="padding-top: 20px;">Sign up!</h3>
Log in
{% else %}
<div style="margin-top: 45px">
Profile
</div>
{% endif %}
</div>
Works in the account-div, but not in the sidebar-div.
Any suggestions?
You have
{% if user.is_authenticated %}
<h3 id="plus" style="padding-top: 20px;">Sign up!</h3>
Log in
{% else %}
why does he have to sign up if he's logged in?
You can try {% if not user.is_authenticated %}