I want to get specific queryset inside my ListView class. The queryset that I want to get is:
user = User.objects.get(username=username)
However, since ListView is class-based view, I can't define what I want.
I tried like this:
**views.py**
class PostListView(ListView):
model = Post
template_name = 'itu_forum/home.html'
context_object_name = 'posts'
ordering = ['-date_posted'] # for normal view [date_posted]
paginate_by = 6
def get_context_data(self, **kwargs):
ctx = super(PostListView, self).get_context_data(**kwargs)
ctx['title'] = 'Ana Sayfa'
return ctx
def get_queryset(self):
queryset = super(PostListView, self).get_queryset()
return queryset.filter(author.username=self.kwargs['username'])
This is the url I want to use. I want to get to specific user's profile:
**urls.py**
path('profile/<str:username>/', views.user_profile, name='user-profile')
href in My Template:
href="{%url 'user-profile' queryset.username %}
I completely messed up. Need help.
you can do
def get_queryset(self):
queryset = super(PostListView, self).get_queryset()
return queryset.filter(author.username=self.request.user.username)
Related
I ask you if you know how put this filters :
class CoursesFilters(django_filters.FilterSet):
class Meta:
model = Courses
exclude = ('description')
in this class view :
class CoursesList(ListView):
model = Courses
template_name = 'courses_list.html'
I used to build my applications using function-based views, and this is my first time use class-based views.
Any idea?
django-filters has a FilterView [readthedocs.io] that can be used:
from django_filters.views import FilterView
class CoursesList(FilterView):
model = Courses
template_name = 'courses_list.html'
filterset_class = CoursesFilters
The filterset_class specifies the FilterSet that. The filter is passed to the template as filter. You thus can render a {{ filter.form }} in the template.
class CoursesList(ListView):
model = Courses
template_name = 'courses_list.html'
def get_context_data(self, **kwargs: any):
context = super().get_context_data(**kwargs)
context['filter'] = CoursesFilters(self.request.GET,
queryset=self.get_queryset())
return context
def get_queryset(self):
return self.object.courses_set.all()
courses_list.html
{{ filter.form.as_p }}
Is there a way to return a dictionary through the get_queryset function of a class based view in Django? I want to pass the array tickets and the string email to my template, but I am only able to pass tickets right now.
Content of views.py:
class UserTicketListView(ListView):
model = Ticket
template_name = 'ticket_system/user_tickets.html'
context_object_name = 'tickets'
ordering = ['-date_posted']
paginate_by = 5
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
email = User.objects.get(username=user).email
return Ticket.objects.filter(author=user).order_by('-date_posted')
class UserTicketListView(ListView):
model = Ticket
template_name = 'ticket_system/user_tickets.html'
context_object_name = 'tickets'
ordering = ['-date_posted']
paginate_by = 5
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
queryset = self.get_queryset()
user = get_object_or_404(User, username=self.kwargs.get('username'))
email = User.objects.get(username=user).email
queryset = queryset.filter(author=user).order_by('-date_posted')
context['user'] = user
context['email'] = email
return context
Using Django Class Based Views, I already have a ListView for Order objects, and I created a FormView to perform advanced searches on these orderers.
However, I'm not sure how to pass the filtered queryset of the FormView to the ListView.
Here is the code, with commented sections to explain the issue:
class OrdersListView(PermissionRequiredCanHandleOrders,
SelectRelatedMixin, PrefetchRelatedMixin,
ModelInContextMixin, SubSectionLastOrders,
RestaurantOrdersOnly,
ListView):
model = Order
paginator_class = DiggPaginator
paginate_by = 15
select_related = ('convive__user',)
prefetch_related = ('orderoperation_set',)
# will use the template named order_list.html
class OrdersAdvancedSearchView(PermissionRequiredCanHandleOrders,
ModelInContextMixin, SubSectionLastOrders,
RestaurantOrdersOnly, RestaurantMixin,
FormView):
model = Order
template_name = "orders/order_advanced_search.html"
form_class = OrderAdvancedSearchForm
def form_valid(self, form):
data = form.cleaned_data
queryset = Order.objects.all()
# Here, I'm using the form content to filter the queryset
# queryset = queryset.filter(some_attribute__in=data['stuff'])
# MY PAIN POINT IS HERE: what I'm supposed to do here ?
# my queryset is filtered, and I need to call OrderListView
# with it.
return super().form_valid(form)
You should use the ListView to filter the queryset with the GET request parameters. For this, add the form to your context and process it when getting the queryset:
def get_queryset(self):
self.form = OrderAdvancedSearchForm(data=self.request.GET or None)
if self.request.GET and form.is_valid():
# filter using the form's cleaned_data
queryset = super().get_queryset().filter(...)
else:
queryset = super().get_queryset()
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) # this calls self.get_queryset() which assigns self.form
context['form'] = self.form
return context
Now in your template you can just render the same form, except its method should be "GET" not "POST".
I'm trying to build data filtering paginated page. Here is my filter
from shop.models import CC
import django_filters
name_values = [("", "---------")] + list(CC.objects.values_list('name', 'name').distinct())
city_values = [("", "---------")] + list(CC.objects.values_list('city', 'city').distinct())
class CCFilter(django_filters.FilterSet):
name = django_filters.ChoiceFilter(choices=name_values)
city = django_filters.ChoiceFilter(choices=city_values)
class Meta:
model = CC
fields = {
'name': ['exact'],
'city': ['exact'],
}
View:
#method_decorator(login_required, name='dispatch')
class BuyView(ListView):
paginate_by = '25'
queryset = CC.objects.all()
context_object_name = "ccs"
template_name = "buy.html"
def get_queryset(self):
queryset = super(BuyView, self).get_queryset()
queryset = CCFilter(self.request.GET, queryset)
return queryset
def get_context_data(self, **kwargs):
context = super(BuyView, self).get_context_data(**kwargs)
context['cart'] = Cart.objects.get(user=self.request.user)
return context
def get_paginate_by(self, queryset):
"""
Paginate by specified value in querystring, or use default class property value.
"""
return self.request.GET.get('per_page', self.paginate_by)
Model:
class CC(models.Model):
number = models.CharField(max_length=19, unique=True)
name = models.CharField(max_length=70)
In documentation it's written that form object is available as context property in template. But when I do {{ ccs.form|crispy }} nothing appears. Though I'm able to filter data with get requests like ?name=christian, it works well. But how can I access form?
The documentation shows that you can either write a view and pass the filter to the template manually, or use the built in FilterView. You are currently using Django's ListView, so the filter won't be passed to the template unless you do it explicitly.
You could try changing your view to use FilterView instead. It would look something like this. I've left out the pagination code to keep it simple.
from django_filters.views import FilterView
#method_decorator(login_required, name='dispatch')
class BuyView(FilterView):
filterset_class = CCFilter
template_name = "buy.html"
context_object_name = "ccs"
def get_queryset(self):
queryset = super(BuyView, self).get_queryset()
queryset = CCFilter(self.request.GET, queryset)
return queryset
def get_context_data(self, **kwargs):
context = super(BuyView, self).get_context_data(**kwargs)
context['cart'] = Cart.objects.get(user=self.request.user)
return context
In the template, you can access the filter with {{ filter }}, and the form with {{ filter.form }}
The pagination in this simple generic view in Django is working, but each page displays all rows, and not the rows for that page.
How can I select the only the records needed for a given page?
class ArticleList(ListView):
"""Get all articles"""
model = Article
template_name = "blog/articles.html"
paginate_by = 4
def get_context_data(self, **kwargs):
context = super(ArticleList, self).get_context_data(**kwargs)
context['articles'] = Article.objects.select_related().all()
return context
Because you've overridden the articles object in get_context_data to return everything. The default implementation does the pagination there, but you've replaced that with your non-paginated queryset.
Instead, define get_queryset and add the select_related there.
Here's how I ended up solving it at first:
class ArticleList(ListView):
"""Get all articles"""
model = Article
template_name = "blog/articles.html"
paginate_by = 1
def get_context_data(self, **kwargs):
context = super(ArticleList, self).get_context_data(**kwargs)
p = Paginator(Article.objects.select_related().all(), self.paginate_by)
context['articles'] = p.page(context['page_obj'].number)
return context
However, after everyones help the best way is:
class ArticleList(ListView):
"""Get all articles"""
model = Article
template_name = "blog/articles.html"
paginate_by = 1
context_object_name = "articles"
def get_queryset(self):
return Article.objects.all().order_by('-date')
Thanks all.