Hello i have a page using paginate_by 10, and instead i'm getting only 9 elements per page, even tho in the element inspector i see 10 grid spaces my for cicle is just being able to fill 9 out of 10 then it goes into the next page.
Views.py
class VideoListView(generic.ListView):
model = Video
template_name = 'index.html'
context_object_name = 'video_list'
paginate_by = 10
def get_queryset(self):
return Video.objects.order_by('-date')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['category_list'] = Category.objects.all()
return context
EDIT AFTER A QUESTION. here's the template logic
<ul id="first-category" class="items-container">
{% for video in video_list %}
{% if video.home ==True %}
<li class="item">
</li>
{% endif %} {% endfor %}
As possible causes i did find that when i do "paginate by 1" the page starts displaying empty pages for the pages that aren't considered in the IF. which makes me think that the if statement is taking into consideration the empty videos even tho they aren't listed.
How can i fix this?
i do want to filter the videos that aren't meant for the home_page
Thanks a lot in advance for the reply
The reason this happens is because you filter in the template, so after the queryset is paginated. Filtering in the template is not a good idea, for example because it will render the pagination incorrect, but it is also inefficent.
You should filter in the view, with:
class VideoListView(generic.ListView):
model = Video
queryset = Video.objects.filter(home=True).order_by('-date')
template_name = 'index.html'
context_object_name = 'video_list'
paginate_by = 10
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['category_list'] = Category.objects.all()
return context
and thus remove the {% if video.home == True %} … {% endif %} part.
Related
Good day everyone.
I am trying to build a form which queries the database based on user data inputs and then returns the results in a new page. but I don't know exactly how to do it and I am getting errors. I've looked for a solution but couldn't find any. Please help me if you know any solutions.
Thanks in advance.
Here are my codes:
forms.py
class AttendanceForm(forms.Form):
course = forms.CharField(max_length=50)
department = forms.CharField(max_length=10)
semester = forms.IntegerField()
views.py
class AttendanceForm(generic.FormView):
form_class = CrsAttForm
template_name = 'office/crsatt_form.html'
success_url = reverse_lazy('office:members_list')
class MembersList(generic.ListView):
template_name = "office/crs_att.html"
context_object_name = 'members'
def get_queryset(self):
return Members.objects.all()
# I know I should use .filter method but how could I set the parameters to data received from the form
urls.py
url(r'^CourseAttendanceForm/$', views.AttendanceForm.as_view(), name='courseattendance'),
url(r'^CourseAttendanceForm/Results/$',views.MembersList.as_view(), name='memebrs_list'),
I think that it will be easier for you to use function based views for this one.
You can do it like this:
views.py
def form_page(request):
form = AttendanceForm()
# you get to this "if" if the form has been filled by the user
if request.method == "POST":
form = AttendanceForm(request.POST)
if form.is_valid():
course = request.POST['course']
department = request.POST['department']
semester = request.POST['semester']
members = Member.objects.filter(#here you do your filters as you already have the course, department and semester variables)
context = {'members': members}
return render(request, 'second_page.html', context)
# if the form hasn't been filled by the user you display the form
context = {'form': form}
return render(request, 'form_page.html', context)
form_page.html
<form method="post" action="{% url 'form_page' %}">
{% csrf_token %}
{{ form }}
<button type="submit">Search!</button>
</form>
urls.py
path('form_page/', views.form_page, name='form_page')
second_page.html
{% for member in members %}
# here you display whatever you want to
{% endfor %}
I want to display data from 2 tables (and more in the future), but something doesnt work in my code.
my views.py:
**imports**
def home(request):
context = {'users': Person.object.all(),
'emails': Email.object.all()
}
return render(request,'app/home.html',context)
class PersonListView(ListView):
model = Person
template_name = 'app/home.html'
context_object_name = 'users'
and in my home.html
{% extends "app/base.html" %}
{% block content %}
{% for user in users %}
Displaying user attributes works fine
{% endfor %}
Here should be emails
{% for email in emails %}
This displaying doesnt work
{% endfor %}
{% endbock content %}
So, displaying users works without any problem, but cant display anything form emails, but if I do it in shell, everything works well
A ListView [Django-doc] is designed to display only one queryset at a time. If you need to pass extra querysets, you can override the get_context_data(..) method [Django-doc]:
class PersonListView(ListView):
model = Person
template_name = 'app/home.html'
context_object_name = 'users'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update(emails=Email.objects.all())
return context
Here we thus pass an extra variable emails to the template rendering engine. Note however that this queryset will not be paginated (or at least not without adding some pagination yourself).
my models.py:
Note that those are views, you need to write these in views.py.
I have a form that when i submit it need to show the details I submitted in the form.
I am really struggling to understand how to get it to display checkbox data.
I went thropugh the django documentation on DetailForms but this didnt really help me with how to display ManyToManyFields.
My template is as follows:
<li>{{theBurger.burger}}</li>
<li>{{theBurger.bun}}</li>
{% for toppings in theBurger.toppings.all %}
<li>{{toppings}}</li>
{% empty %}
<p>No toppings!</p>
{% endfor %}
<li>{{theBurger.sauces}}</li>
{% for extras in theBurger.extras.all %}
<li>{{theBurger.extras}}</li>
{% empty%}
<p>No extras!</p>
{% endfor %}
My view is as followes:
class OrderDetailView(DetailView):
context_object_name = 'theBurger'
slug_field = 'id'
model = models.Burger
def get_context_data(self, **kwargs):
context = super(OrderDetailView, self).get_context_data(**kwargs)
context['now'] = timezone.now()
return context
I can get the page to display all the other information except information that has been submitted via checkboxes. the response that is being sent is:
<QueryDict: {'csrfmiddlewaretoken':
['l6Qq7tg89cueHV2Fl6Qq7tg89cueHV2F2WrzrbJ'],
'burger': ["Aurion's Famous Beef Burger"], 'bun': ['White Bread'],
'toppings': ['15', '1
6'], 'sauces': ['Our Zesty Barbaque Sauce'], 'Submit': ['Git my food!']}>
Lastly here is the form:
class BurgerForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(BurgerForm, self).__init__(*args, **kwargs)
self.fields['toppings'].widget = forms.CheckboxSelectMultiple()
for field_name in self.fields:
field = self.fields.get(field_name)
if field and isinstance(field , forms.TypedChoiceField):
field.choices = field.choices[1:]
self.fields['extras'].widget = forms.CheckboxSelectMultiple()
class Meta:
model = Burger
fields = ['burger', 'bun', 'toppings', 'sauces', 'extras']
Can someone point out what ive done wrong?
Darn after ploughing though a gazillion google linked I came across this:
http://www.joshuakehn.com/2013/6/23/django-m2m-modelform.html
I tried to remove the:
Commit=False
from:
post = form.save()
in the forms.py file and it works now. I wasted a lot of time on this so I hope it helps someone else.
I'm trying to make a simple messaging feature for my web app. I have the following views for creating and listing conversations i.e. groups of messages between two users.
views.py
class CreateMessageView(CreateView):
model = Message
fields = ['msg']
def form_valid(self, form):
form.instance.frm = frm = self.request.user
form.instance.to = to = User.objects.get(id=self.kwargs['pk'])
form.instance.thread = "%s & %s" % (frm, to) if int(frm.id) < int(to.id) else "%s & %s" % (to, frm)
return super(CreateMessageView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(CreateMessageView, self).get_context_data(**kwargs)
context['to'] = User.objects.get(id=self.kwargs['pk']).get_full_name()
return context
def get_success_url(self):
return reverse('main:message-list')
class ListMessageView(ListView):
model = Message
def get_queryset(self):
return Message.objects.filter(Q(to=self.request.user) | Q(frm=self.request.user)).order_by('-created', 'thread')
message_list.html
<h3>Messages</h3>
{% regroup object_list by thread as threads %}
<ul>
{% for item in threads %}
<li> {{ item.grouper }} </li>
{% empty %}
<li>No messages to show. Send a message to someone today!</li>
{% endfor %}
</ul>
I am trying to use the regroup feature to group messages with the same conversation name. However, this shows the conversation name on the list, but I want to show the name of the person on the other end of the conversation. How can I achieve this?
I am using django-extra-views in order to have sortable tables in my Django ListViews.
I'm not 100% sure of why I can't get it working, but I've always found working from tests.py difficult wrt templates.
So I have this in my views.py
class PartTypePartList(SortableListMixin, generic.ListView):
model = PartNumber
template_name = 'inventory/newparttype_list.html'
sort_fields = ['name',]
paginate_by = 25
def get_queryset(self):
self.parttype = self.kwargs['parttype']
return PartNumber.objects.filter(fds_part_type=self.parttype)
def get_context_data(self, **kwargs):
context = super(PartTypePartList, self).get_context_data(**kwargs)
context['parttype'] = self.parttype
return context
And in urls.py
url(r'^newparttype/(?P<parttype>\d{2})/$', views.PartTypePartList.as_view(), name='new_part_type_view'),
And with these two we are getting the list as expected.
In the relevant template:
Name
asc name
desc name
{% if sort_helper.is_sorted_by_name %} ordered by name {{ sort_helper.is_sorted_by_name }} {% endif %}
The issue is that there is no sorting happening. In particular,
{{ sort_helper.get_sort_query_by_name }} and
{{ sort_helper.get_sort_query_by_name_asc }} and
{{ sort_helper.get_sort_query_by_name_desc }}
each return an empty string.
What am I doing wrong?
I was using django-tables2 but the owner admitted he would not be continuing dev on it and I'm not skilled enough or time rich enough to take it on myself.
[EDIT]
I believe this still deserves a solution, but I've re-written the view to be a FBV rather than a CBV and am manipulating the data accordingly
[/EDIT]
You need to call get_queryset parent method:
def get_queryset(self):
self.parttype = self.kwargs['parttype']
qs = super(PartTypePartList, self).get_queryset()
qs = qs.filter(fds_part_type=self.parttype)
return qs