I am trying display all courses from my course model to the users, but seems i am getting it wrong.
here is my code;
views.py
def course_list(request, category_slug=None):
category = None
categories = Category.objects.all()
courses = Courses.objects.filter(available=True)
if category_slug:
category = get_object_or_404(Category, slug=category_slug)
courses = courses.filter(category=category)
return render(request,'courses/content/list.html', {'category': category, 'categories': categories, 'courses': courses})
def course_detail(request, id, slug):
course = get_object_or_404(Courses, id=id, slug=slug, available=True)
return render(request, 'courses/content/detail.html', {'course': course})
here is the code for my list.html
{%block content %}
<section id="about-home">
<h2>Courses</h2>
</section>
<!-- courses section starts -->
<section id="course">
<h1>Our Amazing Courses</h1>
<p>Replenish man have thing gathering lights yielding shall you</p>
<div class="course-box">
{% for course in courses %}
<div onclick="window.location.href='{{ course.get_absoule.url}}';" class="courses">
<img
src="{% if courses.cover %}{{ courses.cover.url }} {% else %} {% static 'images/c3.jpg' %}{% endif %}"
alt="{{ courses.name }}" />
<div class="details">
<span>{{courses.updated}}</span>
<h6>{{courses.name}}</h6>
<div class="star">
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="far fa-star"></i>
<span>(23)</span>
</div>
</div>
<div class="cost">${{courses.price_display}}</div>
</div>
{% endfor %}
</section>
{%endblock content%}
the above codes is for my views.py and list.html
Related
I made a blog app in which I want to add pagination both on home page and category page. but after a lot of efforts I didn't get how to use it in the category page. I use 2 parameters in category view and I don' know how to fix it now. whenever I click on category "That page number is not an integer" displays.
views.py:
def allpost(request):
postData = Post.objects.all()
paginator = Paginator(postData, 5) # Show 5 contacts per page.
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'posts.html', {'page_obj': page_obj})
def CategoryView(request, cats='category__title'):
category_posts = Post.objects.all()
paginator = Paginator(category_posts, 5)
# We don't need to handle the case where the `page` parameter
# is not an integer because our URL only accepts integers
try:
category_posts = paginator.page('cats')
except EmptyPage:
# if we exceed the page limit we return the last page
category_posts = paginator.page(paginator.num_pages)
return render(request, 'categories.html', {'category_posts': category_posts})
urls.py:
path('category/<str:cats>/', views.CategoryView, name ="category"),
categories.html
{% extends 'base.html' %}
{%block content%}
<h1> Category: {{ cats }} </h1>
{% for post in category_posts %}
<div class="container mt-3">
<div class="row mb-2">
<div class="col-md-6">
<div class="card flex-md-row mb-4 box-shadow h-md-250">
<div class="card-body d-flex flex-column align-items-start">
<strong class="d-inline-block mb-2 text-primary">{{ post.category }}</strong>
<h3 class="mb-0">
<a class="text-dark" href="{% url 'detail' post.id %}">{{post.title}}</a>
</h3>
<div class="mb-1 text-muted">{{ post.public_date }}</div>
<p class="card-text mb-auto">{{ post.summary }}</p>
Continue reading
</div>
<img class="card-img-right flex-auto d-none d-md-block" data-src="holder.js/200x250?theme=thumb" alt="Thumbnail [200x250]" style="width: 200px; height: 250px;" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22200%22%20height%3D%22250%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20200%20250%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_182c981dfc3%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A13pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_182c981dfc3%22%3E%3Crect%20width%3D%22200%22%20height%3D%22250%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2256.20000076293945%22%20y%3D%22131%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" data-holder-rendered="true">
</div>
</div>
</div>
</div>
{% endfor %}
{% include 'pagination.html' %}
{%endblock%}
pagination.html
<div class="container mt-3">
<nav aria-label="Page navigation example">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item"><a class="page-link" href="/?page=1">First</a></li>
<li class="page-item"><a class="page-link" href="/?page={{ page_obj.previous_page_number }}">Previous</a></li>
{% endif %}
<li class="page-item"><a class="current" href="/?page={{ page_obj.number }} of {{ page_obj.paginator.num_pages }}">1</a></li>
{% if page_obj.has_next %}
<li class="page-item"><a class="page-link" href="/?page={{ page_obj.next_page_number }}">Next</a></li>
<li class="page-item"><a class="page-link" href="/?page={{lastpage}}">Last</a></li>
{% endif %}
</div>
I am very confused already in category views function to use parameter issue. so that I didn't use that code in pagination.html.
===== in view.py ======
from django.core.paginator import Paginator
def HomeView(request):
show_data = VehicleModel.objects.all() # Queryset For pagiantion
# Pagination code start
paginator = Paginator(show_data, 3, orphans=1)
page_number = request.GET.get('page')
show_data = paginator.get_page(page_number)
# Pagination code end
context = {'page_number':page_number}
return render(request,'dashboard.html',context)
===== in html file ======
<!-- Pagination Block with page number -->
<div class="container mt-5">
<div class="row float-right ">
<span class="m-0 p-0">
{% if carset.has_previous %} # <!-- For Previous Button -->
<a class="btn btn-outline-info" href="?page={{carset.previous_page_number}}&ok=#ok">Previous</a>
{% endif %}
<span>{% for pg in carset.paginator.page_range %} # <!-- For Page Numbers Buttons -->
{% if carset.number == pg %}
<a href="?page={{pg}}" class="btn btn-sm btn-primary">
<span class="badge">{{pg}}</span>
</a>
{% else %}
<a href="?page={{pg}}" class="btn btn-sm btn-secondary">
<span class="badge">{{pg}}</span>
</a>
{% endif %}
{% endfor %}</span>
{% if carset.has_next %} # <!-- For Next Button -->
<a class="btn btn-outline-info" href="?page={{carset.next_page_number}}&ok=#ok">Next</a>
{% endif %}
</span>
</div>
</div>
=========== Your code is like this ==============
here you passed the category parameter in the function so must pass the category title with the calling URL of this CategoryView(request, cats='category__title') function
def CategoryView(request, cats='category__title'):
category_posts = Post.objects.all()
paginator = Paginator(category_posts, 5)
with this CategoryView(request, cats='category__title') you want all Posts ???
def
CategoryView(request, cats='category__title'):
category_posts = Post.objects.filter(cats__title = cats)
paginator = Paginator(category_posts, 5)
ator = Paginator(category_posts, 5)
After I posted my comment and decided to refresh the page it adds the same comment over and over on every refresh how can I stop this?
The code for the comment review is at the far bottom in the template.html.
And the review code is under "def product_detail" in the views.py.
Can someone give me some tips so if I refresh it dosen't do another post?
template file:
{% extends "base.html" %}
{% load static %}
{% block page_header %}
<div class="container header-container">
<div class="row">
<div class="col"></div>
</div>
</div>
{% endblock %}
{% block content %}
<div class="overlay"></div>
<div class="container-fluid">
<div class="row">
<div class="col-12 col-md-6 col-lg-4 offset-lg-2">
<div class="image-container my-5">
{% if product.image %}
<a href="{{ product.image.url }}" target="_blank">
<img class="card-img-top img-fluid" src="{{ product.image.url }}" alt="{{ product.name }}">
</a>
{% else %}
<a href="">
<img class="card-img-top img-fluid" src="{{ MEDIA_URL }}noimage.png" alt="{{ product.name }}">
</a>
{% endif %}
</div>
</div>
<div class="col-12 col-md-6 col-lg-4">
<div class="product-details-container mb-5 mt-md-5">
<p class="mb-0">{{ product.name }}</p>
<p class="lead mb-0 text-left font-weight-bold">${{ product.price }}</p>
{% if product.category %}
<p class="small mt-1 mb-0">
<a class="text-muted" href="{% url 'products' %}?category={{ product.category.name }}">
<i class="fas fa-tag mr-1"></i>{{ product.category.friendly_name }}
</a>
</p>
{% endif %}
{% if product.get_rating > 0 %}
<small class="text-muted"><i class="fas fa-star mr-1"></i>{{ product.get_rating }} / 5</small>
{% else %}
<small class="text-muted">No Rating</small>
{% endif %}
{% if request.user.is_superuser %}
<small class="ml-3">
Edit |
<a class="text-danger" href="{% url 'delete_product' product.id %}">Delete</a>
</small>
{% endif %}
<p class="mt-3">{{ product.description }}</p>
<form class="form" action="{% url 'add_to_bag' product.id %}" method="POST">
{% csrf_token %}
<div class="form-row">
{% with product.has_sizes as s %}
{% if s %}
<div class="col-12">
<p><strong>Size:</strong></p>
<select class="form-control rounded-0 w-50" name="product_size" id='id_product_size'>
<option value="xs">XS</option>
<option value="s">S</option>
<option value="m" selected>M</option>
<option value="l">L</option>
<option value="xl">XL</option>
</select>
</div>
{% endif %}
<div class="col-12">
<p class="mt-3"><strong>Quantity:</strong></p>
<div class="form-group w-50">
<div class="input-group">
<div class="input-group-prepend">
<button class="decrement-qty btn btn-black rounded-0"
data-item_id="{{ product.id }}" id="decrement-qty_{{ product.id }}">
<span class="icon">
<i class="fas fa-minus"></i>
</span>
</button>
</div>
<input class="form-control qty_input" type="number"
name="quantity" value="1" min="1" max="99"
data-item_id="{{ product.id }}"
id="id_qty_{{ product.id }}">
<div class="input-group-append">
<button class="increment-qty btn btn-black rounded-0"
data-item_id="{{ product.id }}" id="increment-qty_{{ product.id }}">
<span class="icon">
<i class="fas fa-plus"></i>
</span>
</button>
</div>
</div>
</div>
</div>
<div class="col{% if s %}-12 mt-2{% endif %}">
<a href="{% url 'products' %}" class="btn btn-outline-black rounded-0 mt-5">
<span class="icon">
<i class="fas fa-chevron-left"></i>
</span>
<span class="text-uppercase">Keep Shopping</span>
</a>
<input type="submit" class="btn btn-black rounded-0 text-uppercase mt-5" value="Add to Bag">
</div>
<input type="hidden" name="redirect_url" value="{{ request.path }}">
{% endwith %}
</div>
</form>
</div>
</div>
</div>
<div class="w-full mt-6">
<h2 class="text-xl">Reviews</h2>
{% if request.user.is_authenticated %}
<form method="post" action="." class="mt-6 mb-6 p-6 bg-gray-100 rounded-xl">
{% csrf_token %}
<div>
<label>Rating</label><br>
<select class="form-control" name="rating">
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected>3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</div>
<div class="form-group">
<label for="comment">Comment</label>
<textarea class="form-control" rows="5" id="comment" name="content"></textarea>
</div>
<button type="submit" class="btn btn-primary mb-2">Submit</button>
</form>
{% endif %}
{% for review in reviews %}
<div class="px-4 py-6 bg-gray-100 rounded-xl mb-4">
<strong>Author:</strong> {{ review.created_by }}<br>
<strong>Rating:</strong> {{ review.rating }}/5<br>
<strong>Date:</strong> {{ review.created_at|date:"Y-m-d" }}<br>
<strong>Comment:</strong><br>
{{ review.content }}
</div>
{% endfor %}
</div>
</div>
{% endblock %}
{% block postloadjs %}
{{ block.super }}
{% include 'products/includes/quantity_input_script.html' %}
{% endblock %}
views.py:
from django.shortcuts import render, redirect, reverse, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.db.models.functions import Lower
from .models import Product, Category, Review
from .forms import ProductForm
# Create your views here.
def all_products(request):
""" A view to show all products, including sorting and search queries """
products = Product.objects.all()
query = None
categories = None
sort = None
direction = None
if request.GET:
if 'sort' in request.GET:
sortkey = request.GET['sort']
sort = sortkey
if sortkey == 'name':
sortkey = 'lower_name'
products = products.annotate(lower_name=Lower('name'))
if sortkey == 'category':
sortkey = 'category__name'
if 'direction' in request.GET:
direction = request.GET['direction']
if direction == 'desc':
sortkey = f'-{sortkey}'
products = products.order_by(sortkey)
if 'category' in request.GET:
categories = request.GET['category'].split(',')
products = products.filter(category__name__in=categories)
categories = Category.objects.filter(name__in=categories)
if 'q' in request.GET:
query = request.GET['q']
if not query:
messages.error(request, "You didn't enter any search criteria!")
return redirect(reverse('products'))
queries = Q(name__icontains=query) | Q(description__icontains=query)
products = products.filter(queries)
current_sorting = f'{sort}_{direction}'
context = {
'products': products,
'search_term': query,
'current_categories': categories,
'current_sorting': current_sorting,
}
return render(request, 'products/products.html', context)
def product_detail(request, product_id):
""" A view to show individual product details """
product = get_object_or_404(Product, pk=product_id)
if request.method == 'POST':
rating = request.POST.get('rating', 3)
content = request.POST.get('content', '')
review = Review.objects.create(
product=product,
rating=rating,
content=content,
created_by=request.user
)
reviews = Review.objects.filter(product=product)
context = {
'product': product,
'reviews': reviews
}
return render(request, 'products/product_detail.html', context)
#login_required
def add_product(request):
""" Add a product to the store """
if not request.user.is_superuser:
messages.error(request, 'Sorry, only store owners can do that.')
return redirect(reverse('home'))
if request.method == 'POST':
form = ProductForm(request.POST, request.FILES)
if form.is_valid():
product = form.save()
messages.success(request, 'Successfully added product!')
return redirect(reverse('product_detail', args=[product.id]))
else:
messages.error(request, 'Failed to add product. Please ensure the form is valid.')
else:
form = ProductForm()
template = 'products/add_product.html'
context = {
'form': form,
}
return render(request, template, context)
#login_required
def edit_product(request, product_id):
""" Edit a product in the store """
if not request.user.is_superuser:
messages.error(request, 'Sorry, only store owners can do that.')
return redirect(reverse('home'))
product = get_object_or_404(Product, pk=product_id)
if request.method == 'POST':
form = ProductForm(request.POST, request.FILES, instance=product)
if form.is_valid():
form.save()
messages.success(request, 'Successfully updated product!')
return redirect(reverse('product_detail', args=[product.id]))
else:
messages.error(request, 'Failed to update product. Please ensure the form is valid.')
else:
form = ProductForm(instance=product)
messages.info(request, f'You are editing {product.name}')
template = 'products/edit_product.html'
context = {
'form': form,
'product': product,
}
return render(request, template, context)
#login_required
def delete_product(request, product_id):
""" Delete a product from the store """
if not request.user.is_superuser:
messages.error(request, 'Sorry, only store owners can do that.')
return redirect(reverse('home'))
product = get_object_or_404(Product, pk=product_id)
product.delete()
messages.success(request, 'Product deleted!')
return redirect(reverse('products'))
You should implement the Post/Redirect/Get architectural pattern [wiki], and thus return a redirect such that the browser will make a GET request next, and thus prevent making another POST request when refreshing the page:
def product_detail(request, product_id):
product = get_object_or_404(Product, pk=product_id)
if request.method == 'POST':
rating = request.POST.get('rating', 3)
content = request.POST.get('content', '')
Review.objects.create(
product=product,
rating=rating,
content=content,
created_by=request.user
)
# redirect to the same page 🖟
return redirect('product_detail', product_id=product_id)
reviews = Review.objects.filter(product=product)
context = {
'product': product,
'reviews': reviews
}
return render(request, 'products/product_detail.html', context)
I have two models
class Post(models.Model):
title = models.CharField(max_length=100)
body = RichTextField(max_length=1000000)
created_at = models.DateTimeField(default=datetime.now, blank = True)
image = ResizedImageField(size=[250, 200], upload_to='img')
and
class Politics(models.Model):
title = models.CharField(max_length=100)
body = RichTextField(max_length=1000000)
created_at = models.DateTimeField(default=datetime.now, blank = True)
image = ResizedImageField(size=[250, 200], upload_to='img',blank = True)
I want to combine them both into one template view and render them on the index.html
Here is my view function
def index(request):
politics = Politics.objects.all()
return render(request,
'index.html',
{'politics':politics, 'posts': Post.objects.all()})
index.html (posts part)
<section id="posts" class="posts">
<div class="container" data-aos="fade-up">
<div class="row g-5">
{% for post in posts reversed %}
{% if forloop.counter < 5 %}
<div class="post-entry-1 col-lg-2 box mx-1">
<img src="{{post.image.url}}" class="post_img">
<div>
<div class="post-meta"><span class="date">{{post.category}}</span> <span class="mx-1">•</span> <span>{{post.created_at}}</span></div>
<h2>{{post.title}}</h2>
</div>
<p class="mb-4 d-block">{{post.body|truncatewords:75}}</p>
<div class="d-flex align-items-center author">
<div class="photo"><img src="{% static 'assets/img/person-1.jpg' %}" alt="" class="img-fluid"></div>
<div class="name">
<h3 class="m-0 p-0">OlePundit</h3>
</div>
</div>
</div>
(politics part)
<div class="row">
{% for politic in politics%}
{% if forloop.counter < 11 %}
<div class="post-entry-1 col-2 mx-1">
<img src="{{politic.image.url}}" alt="" class="post_img">
<div class="post-meta">
<span class="date">{{politic.category}}</span>
<span class="mx-1">•</span>
<span>{{politic.created_at}}</span>
</div>
<h2 class="mb-2">{{politic.title}}</h2>
<span class="author mb-3 d-block">Ole Pundit</span>
<p class="mb-4 d-block">{{politic.body| safe | truncatewords:20}}</p>
</div>
{% endif %}
{% endfor %}
</div>
However, only the 'politics' object is being rendered. What could be wrong?
try this or the problem will be in template file
def index(request):
politics = Politics.objects.all()
posts = Post.objects.all()
return render(request,
'index.html',
{'politics':politics, 'posts': posts})
How do I add pagination to this form's search functionality?
By default, on page refresh, the HTML template for loop shows all the results for all the courses. When the user types in criteria into the form, the form filters the course results template for loop based on what the user typed. Is there a way on page refresh to show only a set limit of course results on the page instead of all of them? Then when a user searches/filters, that pagination limit of X number of course results on a page will still need to show but still applied to the search criteria/filter.
HTML:
<form id='courseform' action="." method="get">
<div class="form-row">
<div class="form-group col-12"> {{ form.title__icontains }} </div>
<div class="form-group col-md-2 col-lg-2"> {{ form.visited_times__gte.label_tag }} {{ form.visited_times__gte }} </div>
<div class="form-group col-md-2 col-lg-2"> {{ form.visited_times__lte.label_tag }} {{ form.visited_times__lte }} </div>
<div class="form-group col-md-2 col-lg-2"> {{ form.created_at__gte.label_tag }} {{ form.created_at__gte }} </div>
<div class="form-group col-md-2 col-lg-2"> {{ form.created_at__lte.label_tag }} {{ form.created_at__lte }} </div>
<div class="form-group col-md-2"> {{ form.skill_level.label_tag }} {{ form.skill_level }} </div>
<div class="form-group col-md-2"> {{ form.subjects.label_tag }} {{ form.subjects }} </div>
</div>
<script src='https://www.google.com/recaptcha/api.js?render=6LeHe74UAAAAAKRm-ERR_fi2-5Vik-uaynfXzg8N'></script>
<div class="g-recaptcha" data-sitekey="6LeHe74UAAAAAKRm-ERR_fi2-5Vik-uaynfXzg8N"></div>
<button type="submit" class="btn btn-primary form-control">Search</button>
<p>This site is protected by reCAPTCHA and the Google
<a target="_blank" rel="noopener noreferrer" href="https://policies.google.com/privacy">Privacy Policy</a> and
<a target="_blank" rel="noopener noreferrer" href="https://policies.google.com/terms">Terms of Service</a> apply.
</p>
</form>
<!--Used to have {{ object.subjects }} next to -->
{% for object in object_list %}
<a class="course_list_link" href="{{ object.get_absolute_url }}"> <p class = "course_list_border"> <strong> {{ object }} </strong> <br/> <br/> {{ object.description }} <br/><br/> {{ object.skill_level }} {{ object.created_at }} Views: {{ object.visited_times }}
{% for sub in object.subjects.all %}
{{ sub.name }}
{% endfor %} </p> </a>
{% endfor %}
Views.py:
class CourseListView(ListView):
template_name = 'courses/course_list.html'
def get_queryset(self):
return Course.objects.all()
def get(self, request, *args, **kwargs):
form = CourseForm(request.GET)
queryset = self.get_queryset()
if form.is_valid():
queryset = queryset.filter(**{k: v for k, v in form.cleaned_data.items() if v})
self.object_list = queryset
return self.render_to_response(self.get_context_data(form=form,object_list=queryset,))
Forms.py:
class CourseForm(forms.Form):
title__icontains = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control col-12', 'autocomplete':'off', 'id':'title_contains', 'type':'search', 'placeholder': 'Course Name'}), required=False)
visited_times__gte = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control', 'autocomplete':'off','id':'view_count_max', 'type':'number', 'min':'0', 'placeholder': '0'}), required=False, validators=[MinValueValidator(0), MaxValueValidator(99999999999999999999999999999999999)])
visited_times__lte = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control', 'autocomplete':'off', 'id':'view_count_min', 'type':'number', 'min':'0', 'placeholder': '1000000'}), required=False, validators=[MinValueValidator(0), MaxValueValidator(99999999999999999999999999999999999)])
created_at__gte = forms.DateField(widget=forms.TextInput(attrs={'class':'form-control', 'autocomplete':'off', 'id':'date_max','type':'date', 'placeholder': 'mm/dd/yyy'}), required=False)
created_at__lte = forms.DateField(widget=forms.TextInput(attrs={'class':'form-control', 'autocomplete':'off', 'id':'date_min', 'type':'date', 'placeholder': 'mm/dd/yyy'}), required=False)
skill_level = forms.ChoiceField(widget=forms.Select(attrs={'class':'form-control', 'autocomplete':'off','id':'skill_level'}), choices = ([('',''), ('Beginner','Beginner'), ('Intermediate','Intermediate'),('Advanced','Advanced'), ]), required=False)
subjects = forms.ModelChoiceField(queryset=Subject.objects.all().order_by('name'), empty_label="", widget=forms.Select(attrs={'class':'form-control', 'autocomplete':'off', 'id':'subjects'}), required=False)
# the new bit we're adding
def __init__(self, *args, **kwargs):
super(CourseForm, self).__init__(*args, **kwargs)
self.fields['title__icontains'].label = "Course Name:"
self.fields['visited_times__gte'].label = "Min Views:"
self.fields['visited_times__lte'].label = "Max Views:"
self.fields['created_at__gte'].label = "Min Date:"
self.fields['created_at__lte'].label = "Max Date:"
self.fields['skill_level'].label = "Skill Level:"
self.fields['subjects'].label = "Subject:"
self.fields['subjects'].queryset = Subject.objects.filter()
Models.py:
class Subject(models.Model):
SUBJECT_CHOICES = ()
name = models.CharField(max_length=20,choices=SUBJECT_CHOICES)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
class Course(models.Model):
SKILL_LEVEL_CHOICES = (
('Beginner', 'Beginner'),
('Intermediate', 'Intermediate'),
('Advanced', 'Advanced'),
)
slug = models.SlugField()
title = models.CharField(max_length=120)
description = models.TextField()
allowed_memberships = models.ManyToManyField(Membership)
created_at = models.DateTimeField(auto_now_add=True)
subjects = models.ManyToManyField(Subject)
skill_level = models.CharField(max_length=20,choices=SKILL_LEVEL_CHOICES, null=True)
visited_times = models.PositiveIntegerField(default=0)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('courses:detail', kwargs={'slug': self.slug})
#property
def lessons(self):
return self.lesson_set.all().order_by('position')
class Meta:
ordering = ('title',)
I tried following some tutorials Django docs one but not sure how to embed that pagination code to mine.
https://docs.djangoproject.com/en/3.0/topics/pagination/
I would appreciate if anyone could help me with this.
Please edit to include your code.
In the page you linked to, read this section:
https://docs.djangoproject.com/en/3.0/topics/pagination/#paginating-a-listview
You just need to add this to your ListView
paginate_by = N
then add
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
last »
{% endif %}
</span>
</div>
to course_list.html.
Serach form (html) :
<!-- Search Form -->
<form class="navbar-search navbar-search-dark form-inline mr-3 d-none d-md-flex ml-lg-auto" action="{% url 'search' %}" method="get">
<div class="form-group mb-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search Tasks" aria-label="Search" name="q">
<button class="btn btn-outline-white my-2 my-sm-0" type="submit">Search</button>
</div>
</form>
views.py
class SearchView(ListView): # taskları arama sonucu listeliyoruz
model = Task
template_name = 'task/search.html'
paginate_by = 5
context_object_name = 'task'
def get_queryset(self):
query = self.request.GET.get("q")
if query:
return Task.objects.filter(
Q(title__icontains=query) | Q(content__icontains=query) | Q(tag__title__icontains=query)).order_by(
'id').distinct()
return Task.objects.all().order_by('id')
In whichever field you want to use pagination, write the code there (example category_detail.html) :
<div class="card-footer py-4">
{% if is_paginated %}
<nav aria-label="...">
<ul class="pagination justify-content-end mb-0">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}" tabindex="-1">
<i class="fas fa-angle-left"></i>
<span class="sr-only">Previous</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">
<i class="fas fa-angle-left"></i>
<span class="sr-only">Previous</span>
</a>
</li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="page-item active">
<a class="page-link" href="#"> {{ i }} </a>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ i }}">{{ i }}<span class="sr-only">(current)</span></a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}">
<i class="fas fa-angle-right"></i>
<span class="sr-only">Next</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">
<i class="fas fa-angle-right"></i>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
I hope the examples worked for you.
I have problem. I want create relationship in model Django. I would like every user to have a different product price. The product must be assigned to the user. It must is to display only after logging in. Unfortunately, the template does not show all parameters.
offers/models.py
class Product(models.Model):
title = models.CharField(max_length=100)
category = models.CharField(max_length=50)
weight = models.FloatField()
description = models.TextField(blank=True)
photo = models.ImageField(upload_to='photos/%Y/%m/%d/')
is_published = models.BooleanField(default=True)
list_date = models.DateField(default=datetime.now, blank=True)
def __str__(self):
return self.title
class UserProduct(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.ForeignKey(Product, on_delete=models.DO_NOTHING)
price = models.FloatField()
is_published = models.BooleanField(default=True)
list_date = models.DateField(default=datetime.now, blank=True)
def __str__(self):
return str(self.user.username) if self.user.username else ''
Products are to be displayed for logged in users.
offers/views.py
def index(request):
context = {
'products': Product.objects.order_by('category').filter(is_published=True)
}
return render(request, 'offers/products.html', context)
def userproduct(request):
context = {
'userproduct': UserProduct.objects.filter(user_id=request.user.id),
'userproduct1': Product.objects.all()
}
return render(request, 'offers/userproducts.html', context)
My template show only title, and price.
offers/userproducts.html
<!-- Offers -->
<section class="text-center mb-4 py-4">
<div class="container">
<div class="row">
{% if user.is_authenticated %}
{% if userproduct %}
{% for product in userproduct %}
<!--Grid column-->
<div class="col-lg-3 col-md-6 mb-4">
<div class="card">
<div class="view overlay">
<img src="{{ product.photo.url }}" class="card-img-top" alt="">
<a href="{% url 'product' product.id %}">
<div class="mask rgba-white-slight"></div>
</a>
</div>
<div class="card-body text-center">
<h6 class="grey-text">{{ product.category }}</h6>
<h5>
<strong>
{{ product.title }}
</strong>
</h5>
<h4 class="font-weight-bold colores">
<strong>{{ product.price }}</strong>
</h4>
</div>
</div>
</div>
<!--Grid column-->
{% endfor %}
{% else %}
<div class="col-sm-12 sm-12">
<p>No Products Available XD</p>
</div>
{% endif %}
{% endif %}
</div>
</div>
</section>
The userproduct queryset that you are iterating over belongs to UserProduct model which doesn't have the fields you're looking for.
This is how it should be:
<!-- Offers -->
<section class="text-center mb-4 py-4">
<div class="container">
<div class="row">
{% if user.is_authenticated %}
{% if userproduct %}
{% for product in userproduct %}
<!--Grid column-->
<div class="col-lg-3 col-md-6 mb-4">
<div class="card">
<div class="view overlay">
<img src="{{ product.title.photo.url }}" class="card-img-top" alt="">
<a href="{% url 'product' product.title.id %}">
<div class="mask rgba-white-slight"></div>
</a>
</div>
<div class="card-body text-center">
<h6 class="grey-text">{{ product.title.category }}</h6>
<h5>
<strong>
{{ product.title.title }}
</strong>
</h5>
<h4 class="font-weight-bold colores">
<strong>{{ product.price }}</strong>
</h4>
</div>
</div>
</div>
<!--Grid column-->
{% endfor %}
{% else %}
<div class="col-sm-12 sm-12">
<p>No Products Available XD</p>
</div>
{% endif %}
{% endif %}
</div>
</div>
</section>
If you need a field from Product model, you should get the Product instance which is title. So:
Price: product.price
Title: product.title.title (product.title also works because of your __str__ function.)
Category: product.title.category
Photo: product.title.photo
And so on ...