I'm trying to use Django (v2.0) pagination with CBV and got issues. The pagination is active because the tag {% if is_paginated %} returns "True" and shows the "PagNav" and the browser path changes too, like this (..?page=1, ...?page=2, etc...) but the displayed elements are all, not 3 just as I set in "paginate_by=3". For example, if the query has 15 elements must to show 3 elements per page and 1 to 5 in the pagination down bellow, but shows all elements. I attach an image and the code:
models.py:
from django.db import models
from django.contrib.auth.models import User
from ckeditor.fields import RichTextField
# Create your models here.
class Project(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE, default=1)
name = models.CharField(verbose_name='Nombre del proyecto', max_length=200)
client = models.CharField(verbose_name='Nombre del cliente', max_length=200)
description = RichTextField(verbose_name='Descripción')
start = models.DateField(verbose_name='Fecha de Inicio', null=True, blank=True)
ending = models.DateField(verbose_name='Fecha de Finalización', null=True, blank=True)
order = models.SmallIntegerField(verbose_name="Orden", default=0)
created = models.DateTimeField(verbose_name='Fecha de creación', auto_now_add=True)
updated = models.DateTimeField(verbose_name='Fecha de modificación', auto_now=True)
class Meta:
verbose_name = 'Proyecto'
verbose_name_plural = 'Proyectos'
ordering = ['-start', 'order']
def __str__(self):
return self.name
class Album(models.Model):
project = models.ForeignKey(Project, verbose_name='Proyecto relacionado', on_delete = models.CASCADE)
title = models.CharField(verbose_name='Título de la imagen', max_length=200)
image = models.ImageField(verbose_name='Imagen', upload_to='portfolio')
created = models.DateTimeField(verbose_name='Fecha de creación', auto_now_add=True)
updated = models.DateTimeField(verbose_name='Fecha de modificación', auto_now=True)
class Meta:
verbose_name = 'Imagen en el album'
verbose_name_plural = 'Imágenes en el album'
ordering = ['created']
def __str__(self):
return self.title
views.py:
#method_decorator(staff_member_required(login_url='login'), name='dispatch')
class AlbumListView(SingleObjectMixin, ListView):
paginate_by = 3
template_name = "core/album_list_form.html"
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=Project.objects.all())
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['project'] = self.object
return context
def get_queryset(self):
return self.object.album_set.all()
#method_decorator(staff_member_required(login_url='login'), name='dispatch')
class ProjectUpdateView(UpdateView):
model = Project
template_name = "core/project_update_form.html"
form_class = ProjectUpdateForm
def get_success_url(self):
return reverse_lazy('portfolio_update', args=[self.object.id]) + '?ok'
urls.py:
from django.urls import path
from . import views
from .views import *
urlpatterns = [
path('', HomePageView.as_view(), name="home"),
path('album/list/<int:pk>', AlbumListView.as_view(), name="portfolio_list_album"),
# Update Views
path('project/update/<int:pk>', ProjectUpdateView.as_view(), name="portfolio_update"),
.
.
.
album_list_form.html:
{% extends "core/base.1.html" %}
{% load static %}
{% block title %}Imágenes de {{project.name}}{% endblock %}
{% block content %}
<div class="container">
<div class="row mt-5 mb-2 ml-1">
<div class="mt-3">
<h2 class="mt-5 mb-0"><a style="color: #343a40;" href="{% url 'portfolio_update' project.id %}">{{project.name}}</a></h2>
<div class="subheading mb-5">Imágenes:</div>
</div>
</div>
</div>
<div class="album py-5 bg-light">
<div class="container" style="margin-bottom: 2.5rem!important; margin-top: 2.5rem!important;">
<div class="row">
{% for album in project.album_set.all %}
<div class="col-md-4">
<div class="card mb-4 shadow-sm">
<img class="card-img-top border-bottom p-2 p-2 p-2 p-2 bg-light" src="{{album.image.url}}" alt="Card image cap">
<div class="card-body">
<p class="card-text" title="{{album.title}}" style="color: #343a40;"><strong>{{album.title|truncatechars:31}}</strong></p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-warning"><i class="fa fa fa-pencil"></i></button>
<button type="button" class="btn btn-sm btn-outline-danger"><i class="fa fa fa-times"></i></button>
</div>
<p></p>
</div>
<small class="text-muted">Última modificación: {{album.updated|date:"SHORT_DATE_FORMAT"}} {{album.updated|time:"h:i a"}}</small>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% if is_paginated %}
<nav aria-label="Page navigation example">
<ul class="pagination pagination-lg justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" style="color:#bd5d38;" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
<span class="sr-only">Previous</span>
</a>
</li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="page-item"><a class="page-link" style="color:#ffffff; background-color: #343a40;" href="?page={{ i }}">{{ i }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" style="color:#bd5d38;" href="?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" style="color:#bd5d38;" href="?page={{ page_obj.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
{% endblock %}
The core of the problem I think is that you write in the template:
{% for album in project.album_set.all %}
You thus make a project object. But regardless whether you paginate your class-based view, you will not paginate a related object manager. You only paginate the object_list.
Probably you can solve it with:
{% for album in object_list %}
Furthermore I think you make the class-based view extremely complicated: this is a class-based view over Albums. Yes, filtered albums, but so the Album should be central here. I think it can be rewritten to:
from django.urls import path
from . import views
from .views import *
urlpatterns = [
path('', HomePageView.as_view(), name="home"),
path('album/list/<int:project_pk>', AlbumListView.as_view(), name="portfolio_list_album"),
path('project/update/<int:pk>', ProjectUpdateView.as_view(), name="portfolio_update"),
]
Then in the view itself:
#method_decorator(staff_member_required(login_url='login'), name='dispatch')
class AlbumListView(ListView):
model = Album
paginate_by = 3
template_name = "core/album_list_form.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['project'] = Project.objects.get(pk=self.kwargs['project_pk'])
return context
def get_queryset(self):
return Album.objects.filter(project_id=self.kwargs['project_pk'])
Related
I'm learning Django and I'm trying to understand its logic. There are 2 models I created. I am designing a job listing page. The first model is "Business". I publish the classes inside this model in my html page and for loop. {% job %} {% endfor %}. But inside my second model in this loop I want to show company_logo class inside "Company" model but I am failing.
Methods I tried to learn;
1- I created a second loop inside the job loop, company loop, and published it failed.
2- I assigned a variable named company_list to the Job class on the views page and made it equal to = Company.objects.all() but it still fails.
Here are my codes.
models.py
from django.db import models
from ckeditor.fields import RichTextField
from djmoney.models.fields import MoneyField
JobTypes = (
('Full-Time', 'Full-Time'), ('Part-Time', 'Part-Time'),
('Internship', 'Internship'), ('Temporary', 'Temporary'), ('Government', 'Government')
)
class Job(models.Model):
job_title = models.CharField( max_length=100, null=True)
job_description = RichTextField()
job_application_url = models.URLField(unique=True)
job_type = models.CharField(max_length=15, choices=JobTypes, default='Full-Time')
#job_category
job_location = models.CharField( max_length=100)
job_salary = MoneyField(max_digits=14, decimal_places=4, default_currency='USD')
created_date = models.DateTimeField(auto_now_add=True)
featured_listing = models.BooleanField( default=False)
company = models.ForeignKey(
"Company", on_delete=models.CASCADE)
def __str__(self):
return f"{self.company}: {self.job_title}"
class Company(models.Model):
created_date = models.DateTimeField(auto_now_add=True)
company_name = models.CharField(max_length=100, unique=True)
company_url = models.URLField(unique=True)
company_logo = models.ImageField(
upload_to='company_logos/')
def __str__(self):
return f"{self.company_name}"
views.py
from django.utils import timezone
from django.shortcuts import render
from .models import Company, Job
def index(request):
jobs = Job.objects.all().order_by('-created_date')[:3]
company_list = Company.objects.all()
context = {
'jobs': jobs,
'company_list':company_list,
}
return render(request, 'index.html', context)
"{% static 'company.company_logo.url' %}" on this page this code is not working. For example, in the coming days I will create a user model and I will have this problem again while publishing the "user.user_name" variable, which will be an example, in my html page. What is the logic here?
index.html
{% extends '_base.html' %}
{% load static %}
{% block content %}
<div class="container">
<!-- Recent Jobs -->
<div class="eleven columns">
<div class="padding-right">
<h3 class="margin-bottom-25">Recent Jobs</h3>
<ul class="job-list">
{% for job in jobs %}
<li class="highlighted"><a href="job-page.html">
<img src="{{ job.company.company_logo.url}}" alt="Logo" class="company-logo">
<div class="job-list-content">
<h4>{{ job.job_title }} <span class="full-time">{{ job.job_type }}</span></h4>
<div class="job-icons">
<span><i class="fa fa-briefcase"></i>{{ job.company }}</span>
<span><i class="fa fa-map-marker"></i> {{ job.job_location }}</span>
{% if job.job_salary %}
<span><i class="fa fa-money"></i> {{job.job_salary}}</span>
{% else %}
<span><i class="fa fa-money"></i>Salary undisclosed</span>
{% endif %}
</div>
</div>
</a>
<div class="clearfix"></div>
</li>
{% endfor %}
</ul>
<i class="fa fa-plus-circle"></i> Show More Jobs
<div class="margin-bottom-55"></div>
</div>
</div>
<!-- Job Spotlight -->
<div class="five columns">
<h3 class="margin-bottom-5">Featured</h3>
<!-- Navigation -->
<div class="showbiz-navigation">
<div id="showbiz_left_1" class="sb-navigation-left"><i class="fa fa-angle-left"></i></div>
<div id="showbiz_right_1" class="sb-navigation-right"><i class="fa fa-angle-right"></i></div>
</div>
<div class="clearfix"></div>
<!-- Showbiz Container -->
<div id="job-spotlight" class="showbiz-container">
<div class="showbiz" data-left="#showbiz_left_1" data-right="#showbiz_right_1" data-play="#showbiz_play_1" >
<div class="overflowholder">
<ul>
{% for job in jobs %}
{% if job.featured_listing %}
<li>
<div class="job-spotlight">
<h4>{{job.job_title}} <span class="freelance">{{job.job_type}}</span></h4>
<span><i class="fa fa-briefcase"></i>{{job.company}}</span>
<span><i class="fa fa-map-marker"></i> {{job.job_location}}</span>
<span><i class="fa fa-money"></i> {{job.job_salary}} / hour</span>
<p>{{ job.job_description | safe | truncatechars:150 }}</p>
Apply For This Job
</div>
</li>
{% endif %}
{% endfor %}
</ul>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
</div>
index.html problem:
urls.py
from django.urls import path
from . import views
from django.conf.urls.static import static
from django.conf import settings
from django.urls import path
from . import views
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('', views.index,name="index"),
#path("jobs/", JobListView.as_view(), name="jobs")
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
the syntax is not
{% static 'company.company_logo.url' %} or **{% static 'company.company_logo.url' %}**
use this instead
{{ company.company_logo.url }}
also if you want to make relations between Job and Company, you can make it like so
inside Job model add this new field
company = models.ForeignKey('Company', on_delete=models.CASCADE)
So that one company can have multiple jobs
Then inside the job for loop in HTML just add this to display company_logo
{% for job in jobs %}
*..........remaining code..........*
<img src="{{ job.company.company_logo.url }}" alt="">
*..........remaining code..........*
{% endfor %}
I need some help when I create a user and user profile accordingly and when I try to access to any user by another user the request turns me on the request I work on not the real user, although, I'm using the slug to specify what the user I click on it maybe I can not explain what happens to me exactly for more explanation, please click on that video to show what I mean: https://www.youtube.com/watch?v=MzSo0ay2_Xk&feature=youtu.be
accounts app
models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.template.defaultfilters import slugify
CHOICE = [('male', 'male'), ('female', 'female')]
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
slug = models.SlugField(max_length=100, unique=True, blank=True)
overview = models.TextField(editable=True, blank=True, default='You have no an Overview yet')
city = models.CharField(max_length=20, blank=False)
phone = models.IntegerField(default=0, blank=True)
sex = models.CharField(max_length=10, default='male', choices=CHOICE)
skill = models.CharField(max_length=100, default='You have no skills yet')
logo = models.ImageField(upload_to='images/', default='images/default-logo.jpg', blank=True)
def __str__(self):
return self.user.username
def save(self, *args, **kwargs):
self.slug = slugify(self.user)
super().save(*args, **kwargs)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(receiver=create_profile, sender=User)
view.py
class ViewProfile(UpdateView):
queryset = UserProfile.objects.all()
template_name = 'accounts/profile.html'
form_class = UpdateInfoForm
slug_field = 'slug'
slug_url_kwarg = 'user_slug'
def get_success_url(self):
return reverse_lazy('accounts:view_profile', kwargs={'user_slug': self.request.user.userprofile.slug})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user_prof = UserProfile.objects.get(user=self.request.user)
context['user_prof'] = user_prof
context['get_favourite'] = User.objects.get(username=self.request.user.username).favorite.all()
return context
def form_valid(self, form):
form.instance.user_slug = self.request.user.userprofile.slug
self.object = form.save()
return super().form_valid(form)
profile.html
{% extends 'base.html' %}
{% block title %} {{ user.first_name }} {{ user.last_name }} Profile {% endblock %}
{% block body %}
<!-- User Profile Section -->
{% if user.is_authenticated %}
<div class="profile">
<div class="container-fluid">
<div class="col-md-1">
<div class="thumbnail">
<div class="row">
<div class="col-xs-12">
<!-- Profile View Section -->
<div class="logo-image text-center">
{% if user.userprofile.logo %}
<div class="my-image">
{% if request.user.username == user.userprofile.slug %}
<a href="{% url 'accounts:user_image' user.userprofile.slug %}">
<img class="img-responsive" src="{{ user.userprofile.logo.url }}">
</a>
<span>
<a href="{% url 'accounts:add_avatar' user.userprofile.slug %}" class="fa fa-camera fa-1x text-center">
<p>Upload Image</p>
</a>
</span>
{% endif %}
</div>
{% else %}
{% load static %}
<div class="my-image">
<img class="img-responsive img-thumbnail" src="{% static 'index/images/default-logo.jpg' %}">
<span>
<a href="{% url 'accounts:add_avatar' user.userprofile.slug %}" class="fa fa-camera fa-1x text-center">
<p>Upload Image</p>
</a>
</span>
</div>
{% endif %}
<h4>{{ user.first_name }} {{ user.last_name }}</h4>
</div>
</div>
<div class="col-xs-12">
<div class="caption">
<ul class="nav nav-pills nav-stacked">
<li role="presentation" class="active">Overview</li>
<li role="presentation" class="">Personal Information</li>
<li role="presentation" class="">Skills</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Information Sections -->
<div class="col-md-8 col-md-offset-3 information">
<div class="overview show" id="overview">
<h2 class="line">Overview</h2>
<p class="lead">{{ user.userprofile.overview }}</p>
<a data-placement="bottom" title="update overview" class="fa fa-edit" data-toggle="modal" data-tooltip="tooltip" data-target=".overview_info"></a>
</div>
<div class="personal-info" id="personal-information">
<h2 class="line">Personal Information</h2>
<p class="lead">City: {{ user.userprofile.city }}</p>
<p class="lead">Phone Number: 0{{ user.userprofile.phone }}</p>
<p class="lead">Sex: {{ user.userprofile.sex }}</p>
<a data-placement="bottom" title="update personal information" class="fa fa-edit" data-toggle="modal" data-tooltip="tooltip" data-target=".personal_info"></a>
</div>
<div class="skill" id="my-skills">
<h2 class="line">Skills:</h2>
<p class="lead">{{ user.userprofile.skill }}</p>
<a data-placement="bottom" title="update skills" class="fa fa-edit" data-toggle="modal" data-tooltip="tooltip" data-target=".skills"></a>
</div>
</div>
<!-- get all questions -->
{% if user_prof.userasking_set.all %}
<div class="col-md-8 col-md-offset-3 user_questions">
<h2 class="line">All Questions You Asked</h2>
{% for questions in user_prof.userasking_set.all %}
<p>{{ questions.title }}</p>
{% endfor %}
</div>
{% endif %}
<!-- get favourites -->
{% if get_favourite %}
<div class="col-md-8 col-md-offset-3 user_questions">
<h2 class="line">Favourites</h2>
{% for fav in get_favourite %}
<p>{{ fav.title }}</p>
{% endfor %}
</div>
{% endif %}
</div>
{% include 'accounts/information_form.html' %}
</div>
{% include 'base_footer.html' %}
{% endif %}
{% endblock %}
self.request.user refers to the currently logged in user. That is why you are getting the same result for all users.
To get what you want, you need to make the following change in your views:
user_prof = UserProfile.objects.get(pk=self.kwargs['pk'])
But also, I'm not sure why you are using an UpdateView when you simply want to display objects? You should use TemplateView instead.
I am trying to implement dynamic tabs in my project that gives multiple tabs based on the values stored in the database.
In my case, I have two values stored in database so it's displaying just two, If I will increase more, it will show accordingly.
Category.objects.filter(category='MEDICINES')
Out[14]: <QuerySet [<Category: FRUITS>, <Category: GRAINS>]>
Here is my models.py file,
from django.db import models
from django.contrib.auth.models import User
STATUS = ((0, "Draft"), (1, "Publish"))
class Category(models.Model):
category_names = (
('DISEASES','DISEASES'),
('MEDICINES','MEDICINES'),
('ENCYCLOPEDIA','ENCYCLOPEDIA'),
)
category = models.CharField(max_length=100, choices=category_names)
sub_category = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.sub_category
class Medicine(models.Model):
title = models.CharField(max_length=200, unique=True)
display_name = models.CharField(max_length=17, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='medicine_posts')
category = models.ForeignKey(Category, on_delete=models.CASCADE)
updated_on = models.DateTimeField(auto_now=True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ["-created_on"]
def __str__(self):
return self.title
def get_absolute_url(self):
from django.urls import reverse
return reverse("medicine_detail", kwargs={"slug": str(self.slug)})
Here it my views.py file,
from django.views import generic
from .models import Medicine, Category
from django.shortcuts import render, get_object_or_404
class MedicineList(generic.ListView):
queryset = {'medicine' : Medicine.objects.filter(status=1).order_by("-created_on"),
'category' : Category.objects.all()
}
#queryset = Medicine.objects.filter(status=1).order_by("-created_on")
print(queryset)
template_name = "medicine.html"
context_object_name = 'element'
#paginate_by = 10
Here is my medicine.html file,
<div class="container">
<div class="row">
<div class="col-md-8 mt-3 left">
<nav>
<div class="nav nav-tabs nav-fill" id="nav-tab" role="tablist">
{% for item in element.category %}
<a class="nav-item nav-link active" id="{{ item.id }}" data-toggle="tab" href="#{{ item }}" role="tab" aria-controls="nav-home" aria-selected="true">{{ item }}</a>
{% endfor %}
</div>
</nav>
{% for item in element.category %}
<div class="tab-content py-3 px-3 px-sm-0" id="nav-tabContent">
<div class="tab-pane fade show active" id="{{ item }}" role="tabpanel" aria-labelledby="{{ item.id}}">
<table class="col-md-8 mt-3 left">
{% for post in element.medicine %}
{% cycle 'row' '' as row silent %}
{% if row %}<tr>{% endif %}
<td style="padding: 10px;">
<div class="card mb-4">
<div class="card-body">
<h6 class="card-title text-center"> {{ post.display_name }}</h6>
</div>
</div>
</td>
{% if not row %}</tr>{% endif %}
{% endfor %}
</table>
</div>
</div>
{% endfor %}
</div>
{% block sidebar %}
{% include 'sidebar.html' %}
{% endblock sidebar %}
</div>
</div>
Please help me out with this code, it;s not working.
Your queryset should not be a dictionary, Django expects a queryset instance here.
Try:
class MedicineList(generic.ListView):
queryset = Category.objects.all()
# or: model = Category
template_name = "medicine.html"
context_object_name = 'element'
I'm kinda new at this, and I believe I have misunderstood some things so I'll try to describe it as best possible.
I have 3 tables(models), Game, Chapter, Thread.
Chapter and Thread are connected with the Game table.
models.py
class Game(models.Model):
title = models.CharField(max_length=100)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.title
class Chapter(models.Model):
title = models.CharField(max_length=80)
content = models.CharField(max_length=10000, null=True)
game = models.ForeignKey(Game, on_delete=models.CASCADE)
def __str__(self):
return self.chapter
class Thread(models.Model):
title = models.CharField(max_length=100)
content = models.CharField(max_length=1000, null=True)
game = models.ForeignKey(Game, on_delete=models.CASCADE)
def __str__(self):
return self.title
views.py
def chapter(request, game_id):
auth = top_menu = True
chapters = Chapter.objects.filter(game=game_id)
return render(request, 'chapters.html', {"chapters": chapters, "auth": auth, "top_menu": top_menu})
def thread(request, game_id):
auth = top_menu =True
threads = Thread.objects.filter(game=game_id)
return render(request, 'threads.html', {"auth": auth, "threads": threads, "top_menu": top_menu})
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', index, name="index"),
path('signup/', signup, name="signup"),
path('logout/', logout_view, name="logout"),
path('login/', login_view, name="login"),
path('<int:game_id>/chapters/', chapter, name="chapter"),
path('<int:game_id>/threads/', thread, name="thread"),
]
index.html
{% extends 'base.html' %}
{% block content %}
<div class="container">
<div class="wrapper">
<div class="row">
<div class="col-lg-12 text-center" style="margin-bottom:80px;">
<h1>Welcome to Solo Rpg Helper</h1>
</div>
</div>
{% if auth %}
<div class="row">
<div class="col-lg-12 text-center">
<h1>Your games:</h1>
<ul class="list-group list-group-flush">
{% for game in games.all %}
<li class="list-group-item">{{ game.title }}</li>
{% endfor %}
</ul>
</div>
</div>
{% else %}
<div class="row">
<div class="col-lg-12 text-center sign-buttons">
<h3>Sign in Sign up</h3>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}
chapter.html
{% extends 'base.html' %}
{% block top_menu %}
<li>Games</li>
<li>Chapters</li>
<li>Threads</li>
{% endblock %}
{% block content %}
<div class="container">
<div class="wrapper">
{% for chapter in chapters.all %}
<div class="row">
<div class="col-lg-6">
<h1>{{ chapter.title }}</h1>
</div>
<div class="col-lg-6">
<p>{{ chapter.content }}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
index.html works fine because I loop the games so I can access game.id.
In the chapter.html I want to use again game.id but I'm not sure how to access it although it is passed in the function chapter in the views.py (I can see it in the terminal).
If I use it like this:
<li>Chapters</li>
it works, but if I use game.id as in index.html:
<li>Chapters</li>
I get the error:
I'm sorry for the long post.
def chapter(request, game_id):
auth = top_menu = True
chapters = Chapter.objects.filter(game=game_id)
return render(request, 'chapters.html', {"chapters": chapters, "auth": auth, "top_menu": top_menu})
You can't use game.id in the chapters.html template at the moment, because the view doesn't include game in the context dictionary.
A typical approach is to use get_object_or_404, to handle the case when no game matches game_id.
from django.shortcuts import get_object_or_404
def chapter(request, game_id):
auth = top_menu = True
game = get_object_or_404(Game, pk=game_id)
chapters = Chapter.objects.filter(game=game_id)
return render(request, 'chapters.html', {"chapters": chapters, "auth": auth, "top_menu": top_menu, "game": game})
I've been trying to display the exact values of model with ManyToMany relation but I just couldn't, all what I've achevied is receiving QuerySet
<QuerySet [<Stack: PHP>, <Stack: js>]>
by adding to template tags
{{ brand.technologies.all }}
But I would like to receive and display 2 fields, name and icon. I've tried with some loops like
{% for brand in brands %}
{% for technologies in brand.technologies.all %} {{ technologies.name }} {{ technologies.icon }} {% endfor %}
{% endfor %}
but it doesn't give any results. There is not problem with syntax because page is displaying and looks like this
image
models.py
STACK = (
('PHP', 'PHP'),
('js', 'JavaScript'),
...
)
STACK_ICONS = (
('/static/icons/stack/php.png', 'PHP'),
('/static/icons/stack/javascript.png', 'JavaScript'),
...
)
class Company(models.Model):
name = models.CharField(max_length=100, blank=False)
students = models.CharField(max_length=3, choices=STUDENTS)
type = models.CharField(max_length=15, choices=TYPES)
workers = models.PositiveIntegerField(validators=[MinValueValidator(1)])
city = models.CharField(max_length=15,choices=CITIES)
company_about = models.TextField(max_length=500, blank=False)
slug = models.SlugField(unique=True)
icon = models.ImageField(blank=True, null=True)
image = models.ImageField(blank=True, null=True)
logo = models.ImageField(blank=True, null=True)
technologies = models.ManyToManyField('Stack')
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Company, self).save(*args, **kwargs)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.name
# object stack relation manytomany with Company
class Stack(models.Model):
name = models.CharField(max_length=30, choices=STACK)
icon = models.CharField(max_length=80, choices=STACK_ICONS)
def __str__(self):
return self.name
views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
...
def comp_list(request):
f = CompanyFilter(request.GET, queryset=Company.objects.all())
return render(request, 'company/comp_list.html', {'filter': f})
def companies(request):
company = get_object_or_404(Company)
return render(request, 'company/comp_list.html', {'company': company})
def home(request):
return render(request, 'company/home.html')
def brands(request, slug):
brand = get_object_or_404(Company, slug=slug)
return render(request, 'company/comp_view.html', {'brand': brand})
def stacks(request):
stack = get_object_or_404(Stack)
return render(request, 'company/comp_view.html', {'stack': stack})
comp_view.html
{% extends 'company/base.html' %}
{% block content %}
<div class="row company-details">
<div class="col col-md-2"></div>
<div class="col col-md-8">
<input class="btn btn-success" type="button" value="Go Back" onclick="history.back(-1)" />
<div class="col col-md-12 company-bg" style="background-image: url('{{ brand.image.url }}'); background-repeat: no-repeat, repeat;">
</div>
<div class="bottom-overlay"></div>
<div class="company-description">
<div class="heading">
<div class="title">About us</div>
<div class="social-media">
Facebook
</div>
</div>
<div class="company-about">
{{ brand.company_about }}
</div>
</div>
<div class="company-stats">
<div class="company-logo-container">
<img class="company-logo" src="{{ brand.logo.url }}">
</div>
<div class="company-attributes">
<div class="field-group">
<div class="field">Type</div>
<div class="value">{{ brand.type }}</div>
</div>
<div class="field-group">
<div class="field">Company size</div>
<div class="value">{{ brand.workers }}+</div>
</div>
<div class="field-group">
<div class="field">Headquarters</div>
<div class="value">{{ brand.city }}</div>
</div>
<div class="field-group">
<div class="field">Open for students</div>
<div class="value">{{ brand.students }}</div>
</div>
</div>
<div class="technologies-section">
<p class="tech-heading">Technologies</p>
<div class="technologies-wrapper">
{{ brand.technologies.all }}
{% for brand in brands %}
{% for technologies in brand.technologies.all %} {{ technologies.name }} {% endfor %}
{% endfor %}
</div>
</div>
</div>
<div class="col col-md-2"></div>
</div>
{% endblock %}
I don't understand why you've suddenly added an outer loop through brands. You don't have anything called brands, and you're successfully accessing all the other data via brand. Just continue to do so, and drop the outer loop.
<div class="technologies-wrapper">
{% for technologies in brand.technologies.all %} {{ technologies.name }} {% endfor %}
</div>