Django - display the right variable - python

My Goal:
If the user has score > 1 display only the jobs that have the correlated category. So, if category.1 (name of the quiz) is DataScience, shows only the jobs that are about Data Science.
What my result is:
If the score > 1 it displays all the job offers present on the database. (as in picture)
What am I doing wrong? Any suggestions?
quiz/models.py
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class Questions(models.Model):
CAT_CHOICES = (
('datascience', 'DataScience'),
('productowner', 'ProductOwner'),
('businessanalyst', 'BusinessAnalyst'),
#('sports','Sports'),
#('movies','Movies'),
#('maths','Maths'),
#('generalknowledge','GeneralKnowledge'),
)
question = models.CharField(max_length = 250)
optiona = models.CharField(max_length = 100)
optionb = models.CharField(max_length = 100)
optionc = models.CharField(max_length = 100)
optiond = models.CharField(max_length = 100)
answer = models.CharField(max_length = 100)
catagory = models.CharField(max_length=20, choices = CAT_CHOICES)
student = models.ManyToManyField(User)
class Meta:
ordering = ('-catagory',)
def __str__(self):
return self.question
jobs/models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class post_job(models.Model):
posizione= models.CharField(max_length=20)
descrizione= models.TextField(max_length=60)
requisiti= models.TextField(max_length=60)
nome_azienda= models.CharField(max_length=20, default=' inserisci nome')
email_referente= models.CharField(max_length=20, default='inserisci email')
core/views.py
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.models import User
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.list import ListView
from .decorators import allowed_user
# Create your views here.
from quiz.models import Questions
from jobs.models import post_job
from functools import wraps
#allowed_user(allowed_roles=['Admin','Students'])
def userProfileView(request, username):
user= get_object_or_404(User, username=username)
jobs = post_job.objects.all()
categories = Questions.CAT_CHOICES
scores = []
for category in categories:
score = Questions.objects.filter(catagory=category[0], student= user).count()
scores.append(score)
context = {
'user' : user, 'categories_scores' : zip( categories,scores),
'jobs': jobs
}
return render(request, 'core/user_profile.html' , context)
core/user_profile.html
{% extends 'base.html'%}
{% block content %}
<br>
<div class="card-header">
<h3> {% if request.user == user %} Il tuo {% endif %} Profilo Utente </h3>
<br>
<h1> Ciao Studente: #{{ user }}</h1>
</div>
<br>
<br>
{% for category,score in categories_scores %}
<div class="card">
<div class="card-header">
{{ category.1 }} Score
</div>
<div class="card-body">
<h5 class="card-title">CONGRATS!</h5>
<p class="card-text"> Here your SCORE: </p>
{{ score }}
{% if score > 1 %}
{% if request.user == user %}
<br>
<br>
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" style="width: 99%" aria-valuenow="99" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="card-text"> Congratulations! Now you can apply to:</p>
<br>
{% for job in jobs %}
<div id="accordion">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
{{job.posizione}} <strong> {{job.nome_azienda}} </strong>
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<ul>
<li> {{job.descrizione}} </li>
<li> {{job.email_referente}} </li>
</ul>
</div>
</div>
</div>
{% endfor %}
{% endif %}
{% else %}
<br>
<br>
<div class="progress">
<div class="progress-bar bg-warning" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="card-text"> Still not meet the requirements to apply, keep going! </p>
{% endif %}
</div>
</div>
<br>
{% endfor %}
{% endblock content %}

On the line in the template,
{% for job in jobs %}
You are expecting this to be just the jobs in which the user has scored > 1, but the code never filtered on it, so it's getting all jobs.
One solution could be to add a field on the post_job Model for Question.category, so that you can filter them down.
Like you said in the comments, there's no connection to between the job and the questions, so that needs to be created.

Related

Error in viewing a product on my django project

Hey guys I get this error thrown up at me when I click a product on my Django project. I assume its a spelling mistake in either my view or models but I cant see anything. I've attach both an image of the error and my code. Any help would be appreciated. apologies if my post does not contain the correct information needed I'm new to coding.
Views
from django.shortcuts import render, get_object_or_404
from .models import Category,Product
def allProdCat(request, category_id=None):
c_page = None
products = None
if category_id != None:
c_page = get_object_or_404(Category, id=category_id)
products = Product.objects.filter(category=c_page, available=True)
else:
products = Product.objects.all().filter(available=True)
return render(request,'shop/category.html',{'category':c_page, 'products':products})
def prod_detail(request,category_id,product_id):
try:
product = Product.objects.get(category_id=category_id,id=product_id)
except Exception as e:
raise e
return render(request,'shop/product.html', {'product':product})
models
import uuid
from django.db import models
from django.urls import reverse
class Category(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False)
name = models.CharField(max_length=250, unique=True)
description = models.TextField(blank=True)
class Meta:
ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def get_absolute_url(self):
return reverse('phoneshop:products_by_category', args=[self.id])
def __str__(self):
return self.name
class Product(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False)
name = models.CharField(max_length=250, unique=True)
description = models.TextField(blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
image = models.ImageField(upload_to='product', blank=True)
stock = models.IntegerField()
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
updated = models.DateTimeField(auto_now_add=True, blank=True, null=True)
class Meta:
ordering = ('name',)
verbose_name = 'product'
verbose_name_plural = 'products'
def get_absolute_url(self):
return reverse('phoneshop:prod_detail', args=[self.category.id, self.id])
def __str__(self):
return self.name
category.html:
{% extends "base.html" %}
{% load static %}
{% block metadescription %}
{% if category %}
{{ category.description|truncatewords:155 }}
{% else %}
Welcome to the cushion store where you can buy comfy and awesome cushions.
{% endif %}
{% endblock %}
{% block title %}
{% if category %}
{{ category.name }} - The Fantastic Electronic ShopnDrop
{% else %}
See our wide range of products including everything from phones to tablets - The Fantastic Electronic ShopnDrop
{% endif %}
{% endblock %}
{% block content %}
<!--Breadcrumb navigation-->
{% if category %}
<div class="row my_row_class">
<div class="mx-auto">
<p>Our Product Collection | {{category.name}}</p>
</div>
</div>
{% endif %}
<div class="mx-auto">
{% if category %}
<img class="my_image" src="{{category.image.url}}" alt="{{category.name}}">
</div>
<br>
<div>
<h1 class="text-center my_title">{{category.name}}</h1>
<p class="text-justify">{{category.description}}</p>
</div>
{% else %}
<img class="my_image my_image_padding" src="{% static 'images/banner.jpg' %}" alt="Our Products Collection">
</div>
<br>
<div>
<h1 class="text-center my_title">Our Products Collection</h1>
<p class="text-justify">Find a phone can be difficult at the best of times. With horrible products and prices its a nightmare
But with our wide range of products, The Fantastic Electronic ShopnDrop, could one be the one stop shop
for you.
</p>
</div>
{% endif %}
<div class="container">
<div class="row mx-auto">
{% for product in products %}
<div class="my bottom margin col-9 col-lg-4 col-sm-12 col-md-4">
<div class="cart text-center" style="min-width: 18rem;">
<img class = "card-img-top my_image"><img src="{{product.image.url}}" alt="{{product.name}}">
<div class="card-body">
<h4>{{product.name}}</h4>
<p>€{{product.price}}</p>
</div>
</div>
</div>
{% endfor %}
</div>
<br>
</div>
{% endblock %}
product.html
{% extends "base.html" %}
{% load static %}
{% block metadescription %}
{{ product.description|truncatewords:155 }}
{% endblock %}
{% block title %}
{{ product.name }} - The Fantastic Electronic ShopnDrop
{% endblock %}
{% block content %}
<div class="row my_prod_row_class">
<div class="mx-auto">
<p>Home | {{product.category}} | {{product.name}}</p>
</div>
<div class="container">
<br>
<div class="row">
<div class="col-12 col-sm-12 col-ml-12 col-lg-6 text-center">
<div style="min-width: 18rem;">
<img src="{{product.image.url}}" alt="{{product.name}}">
</div>
</div class="col-12 col-sm-12 col-md-12 col-lg-6">
<div>
<div>
<h1 class="my_prod_title"></h1>{{product.name}}</h1>
<p>€{{product.price}}</p>
<p class="my_title">Product Description</p>
<p class="text-justify my_prod_text">{{product.description}}</p>
{% if product.stock == 0%}
<p class="text-justify my_prod_text"><b>Out of Stock</b></p>
{% else %}
Add to Cart
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
urls
from django.urls import path
from . import views
app_name ='phoneshop'
urlpatterns = [
path('', views.allProdCat, name ='allProdCat'),
path('<uuid:category_id>/', views.allProdCat, name='products_by_category'),
path('<uuid:cateogry_id>/<uuid:product_id>/', views.prod_detail, name='prod_detail'),
]

How to add multiple entry to multiple model which have one to one relationship in django?

So I have these two models
class Question(models.Model):
question_image = models.ImageField(upload_to="Questions/images", default="")
subject = models.CharField(max_length=100)
topic = models.CharField(max_length=100)
type = models.CharField(max_length=100)
exam_type = models.CharField(max_length=100)
date_asked = models.DateField(default="")
class Option(models.Model):
question_id = models.ForeignKey(Question, on_delete=models.CASCADE)
text = models.CharField(max_length=100)
text.null = True
text.blank = True
option_image = models.ImageField(upload_to="Options/images", default="")
option_image.null =True
option_image.blank =True
is_correct = models.BooleanField()
You see the question has one two many relationships with the options
Now I want to add question and corresponding to that question multiple options in the option table. So if a question with id=1 will have multiple option in option table with question_id = 1.
So I have made these two forms
from django import forms
from practice.models import Question
from practice.models import Option
from django.forms import ModelForm
class QuestionForm(ModelForm):
class Meta:
model = Question
fields = ['question_image', 'subject', 'topic', 'type' , 'exam_type' , 'date_asked']
class OptionForm(ModelForm):
class Meta:
model = Option
fields = ['text' , 'option_image' , 'is_correct']
Now in the HTML template in frontend I want to be able to add as many options I want so I have written this HTML code. The javascript code required to add more options is yet to be done but you get the point I am going to have multiple option forms and one question form. Look at HTML below for now lets just have two option forms.
{% extends "users/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
<div class="content-section">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Add Question</legend>
{{ q_form|crispy }}
<h4 class="border-bottom mb-4 pdb-2" style="padding-bottom : 1rem;">Options
<button type="button" class="add-btn btn btn-success">+ Add Options</button>
</h4>
<div class="container text-left" id="option-list">
<div class="row">
<div class="col-lg-4 col-xl-4 col-md-4 col-sm-12">
{{ o_form.text| as_crispy_field }}
</div>
<div class="col-lg-4 col-xl-4 col-md-4 col-sm-12">
{{ o_form.option_image| as_crispy_field }}
</div>
<div class="col-lg-4 col-xl-4 col-md-4 col-sm-12">
{{ o_form.is_correct| as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-lg-4 col-xl-4 col-md-4 col-sm-12">
{{ o_form.text| as_crispy_field }}
</div>
<div class="col-lg-4 col-xl-4 col-md-4 col-sm-12">
{{ o_form.option_image| as_crispy_field }}
</div>
<div class="col-lg-4 col-xl-4 col-md-4 col-sm-12">
{{ o_form.is_correct| as_crispy_field }}
</div>
</div>
</div>
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Add Question</button>
</div>
</form>
</div>
</div>
{% endblock content %}
This is my views.py
from django.shortcuts import render,redirect
from django.http.response import HttpResponse
from .forms import QuestionForm , OptionForm
def add(request):
q_form = QuestionForm()
o_form = OptionForm()
if request.method == 'POST':
u_form = QuestionForm(request.POST, request.FILE)
o_form = OptionForm(request.POST,
request.FILE,
instance=request.question)
if u_form.is_valid() and o_form.is_valid():
u_form.save()
p_form.save()
print("everthing saved")
return redirect('index')
else:
print("not saved")
return redirect('index')
else:
q_form = QuestionForm()
o_form = OptionForm()
context = {
'q_form' : q_form,
'o_form' : o_form
}
return render(request,'add_question/add.html' , context)
SO my question is how do I add multiple options to the same question id. And how do I pass the question id or the question instance to the options form so that it knows which question I am referring to add option. I want to add multiple options for one question how can I do this.
Thanks for help in advance!

Django - template - reduce for loop repetition, reduce sqlite3 db query

I find myself repeatedly cycling through the same set of data, accessing database several time for the same loops to achieve displaying the correct data on one template, here's the code:
<!-- item images and thumbnails -->
<div class="row">
<div class="col-12 col-sm-8">
<div id="item{{item.pk}}Carousel" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
{% for image in item.itemimage_set.all %}
<li data-target="#item{{item.pk}}Carousel" data-slide-to="{{forloop.counter0}}"
{% if forloop.first %} class="active" {% endif %}></li>
{% endfor %}
</ol>
<div class="carousel-inner shadow-lg rounded-sm">
{% for image in item.itemimage_set.all %}
<div class="carousel-item {% if forloop.first %} active {% endif %}">
<img src="{{image.image.url}}" class="d-block w-100" alt="...">
</div>
{% endfor %}
</div>
{% if item.itemimage_set.count > 1 %}
<a class="carousel-control-prev" href="#item{{item.pk}}Carousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#item{{item.pk}}Carousel" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
{% endif %}
</div>
</div>
<div class="pl-sm-0 col-12 col-sm-4 d-flex flex-wrap align-content-start">
{% for image in item.itemimage_set.all %}
<div class="col-4
{% if item.itemimage_set.count > 3 %}
col-sm-6
{% else %}
col-sm-8
{% endif %}
mt-2 px-1 mt-sm-0 pb-sm-2 pt-sm-0 mb-0">
<img src="{{image.image.url}}" alt="" class="col-12 p-0 rounded-sm shadow-sm"
data-target="#item{{item.pk}}Carousel" data-slide-to="{{forloop.counter0}}">
</div>
{% endfor %}
</div>
</div>
<!-- /item images and thumbnails -->
The above code renders the item's itemimage bootstrap carousel and on the same page, an extra carousel modal:
<!-- itemImageModal -->
<div class="modal fade" id="itemImageModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered col-12 col-md-8 modal-lg" role="document">
<div class="modal-content">
<div class="col-12 px-0">
<div id="itemImage{{item.pk}}Carousel" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
{% for image in item.itemimage_set.all %}
<li data-target="#itemImage{{item.pk}}Carousel" data-slide-to="{{forloop.counter0}}"
{% if forloop.first %} class="active" {% endif %}></li>
{% endfor %}
</ol>
<div class="carousel-inner shadow-lg rounded-sm">
{% for image in item.itemimage_set.all %}
<div class="carousel-item {% if forloop.first %} active {% endif %}">
<img src="{{image.image.url}}" class="d-block w-100" alt="...">
</div>
{% endfor %}
</div>
{% if item.itemimage_set.count > 1 %}
<a class="carousel-control-prev" href="#itemImage{{item.pk}}Carousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#itemImage{{item.pk}}Carousel" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
{% endif %}
</div>
</div>
</div>
</div>
</div>
Data structure:
class Item(models.Model):
name = ... etc.
class ItemImage(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
image = models.ImageField(upload_to='itemimages', null=True, blank=True)
As you can see, there are 5 forloop cycles in the template which leads to frequent queries from the database over the same set of data.
What I've tried:
I've tried to replace {% for image in item.itemimage_set.all %} with {% for image in item.load_related_itemimage %}, and in the models.py:
class Item(models.Model):
name = ...
def load_related_itemimage(self):
return self.itemimage_set.prefetch_related('image')
and this prompt error:
'image' does not resolve to an item that supports prefetching - this is an invalid parameter to prefetch_related().
I'm actually quite new to django and am not sure how to use select_related or prefetch_related but so far I've employed them and managed to reduce database query from 150 to 30+. And I think the frequency can be further reduced due to the silly cycles above as you can see.
forward the Debug Toolbar data for the page:
SELECT "appname_itemimage"."id",
"appname_itemimage"."item_id",
"appname_itemimage"."image"
FROM "appname_itemimage"
WHERE "appname_itemimage"."item_id" = '19'
5 similar queries. Duplicated 5 times.
5 similar queries. Duplicated 5 times. is bad right?
view.py
class ItemDetailView(DetailView):
'''display an individual item'''
model = Item
template_name = 'boutique/item.html'
Thanks for #Iain Shelvington's answer, his solution for the above code works like a charm, how about this:
I think they are related so I didn't separate this to raise another question -- what if the item itself is in a forloop? how to use prefetch_related in this situation? thanks!
{% for item in subcategory.item_set.all %}
<img src="{{ item.itemimage_set.first.image.url }}">
{% endfor %}
because I need to access item.itemimage_set when looping through subcateogry.item_set, and this is a much worse problem than before, because it raises 19 repetition in loading itemimage
This template is rendered by a ListView
class CategoryListView(ListView):
'''display a list of items'''
model = Category
# paginate_by = 1
template_name = 'boutique/show_category.html'
context_object_name = 'category_shown'
def get_queryset(self):
qs = super().get_queryset().get_categories_with_item()
self.gender = self.kwargs.get('gender') # reuse in context
gender = self.gender
request = self.request
# fetch filter-form data
self.category_selected = request.GET.get('category_selected')
self.brand_selected = request.GET.get('brand_selected')
self.min_price = request.GET.get('min_price')
self.max_price = request.GET.get('max_price')
if gender == 'women':
self.gender_number = 1
elif gender == 'men':
self.gender_number = 2
else:
raise Http404
get_category_selected = Category.objects.filter(
gender=self.gender_number, name__iexact=self.category_selected).first()
category_selected_pk = get_category_selected.pk if get_category_selected else None
get_subcategory_selected = SubCategory.objects.filter(
category__gender=self.gender_number, name__iexact=self.category_selected).first()
subcategory_selected_pk = get_subcategory_selected.pk if get_subcategory_selected else None
category_pk = category_selected_pk if category_selected_pk else self.kwargs.get(
'category_pk')
subcategory_pk = subcategory_selected_pk if subcategory_selected_pk else self.kwargs.get(
'subcategory_pk')
# print('\nself.kwargs:\n', gender, category_pk, subcategory_pk)
if gender and not category_pk and not subcategory_pk:
qs = qs.get_categories_by_gender(gender)
# print('\nCategoryLV_qs_gender= ', '\n', qs, '\n', gender, '\n')
return qs
elif gender and category_pk:
qs = qs.filter(pk=category_pk)
# print('\nCategoryLV_qs_category= ', '\n', qs, '\n')
return qs
elif gender and subcategory_pk:
qs = SubCategory.objects.annotate(Count('item')).exclude(
item__count=0).filter(pk=subcategory_pk)
self.context_object_name = 'subcategory_shown'
# print('\nCategoryLV_qs_sub_category= ', '\n', qs, '\n')
return qs
def get_validated_cats(self):
categories_validated = []
subcategories_validated = []
items_validated = []
brand_selected = self.brand_selected
min_price = self.min_price
if min_price == '' or min_price is None:
min_price = 0
max_price = self.max_price
if max_price == '' or max_price is None:
max_price = 999999
for item in Item.objects.select_related('category', 'subcategory', 'tag').filter(category__gender=self.gender_number):
if int(min_price) <= item.final_price < int(max_price):
if brand_selected is None or brand_selected == 'бренд' or item.brand.name == brand_selected:
items_validated.append(item)
if item.category not in categories_validated:
categories_validated.append(item.category)
if item.subcategory not in subcategories_validated:
subcategories_validated.append(item.subcategory)
return categories_validated, subcategories_validated, items_validated
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['brands'] = Brand.objects.all()
cat_valid, subcat_valid, items_valid = self.get_validated_cats()
context['filter_context'] = {
'gender': self.gender,
'gender_number': self.gender_number,
'category_selected': self.category_selected,
'brand_selected': self.brand_selected,
'min_price': self.min_price,
'max_price': self.max_price,
'categories_validated': cat_valid,
'subcategories_validated': subcat_valid,
'items_validated': items_valid,
}
# print(context)
return context
You should use prefetch_related to prefetch "itemimage_set" so that every time you access item.itemimage_set.all you get the cached result
item = get_object_or_404(Item.objects.prefetch_related('itemimage_set'), pk=pk)
For a DetailView
class ItemDetailView(DetailView):
model = Item
queryset = Item.objects.prefetch_related('itemimage_set')

Django Template Filter With Respect to Boolean Variable

My Html
{% for category in categories %}
<div class="row">
<h3 style="padding-left: 15px; padding-bottom: 15px">{% filter upper %}{{ category.name }}{% endfilter %}</h3>
</div>
<div class="row">
{% with products=category.product.all|is_available:True %}
{% for product in products|slice:":4" %}
<div class="product-width col-xl-3 col-lg-3 col-md-3 col-sm-6 col-12 mb-30">
<div class="product-wrapper">
<div class="product-img">
<a href="{% url 'shop:product' category.name product.id %}">
<img alt="" src="{{product.image.all.0.image.url }}">
</a>
<div class="product-action">
<a class="action-wishlist" href="#" title="Wishlist">
<i class="ion-android-favorite-outline"></i>
</a>
<a class="action-cart" href="#" title="Add To Cart">
<i class="ion-android-add"></i>
</a>
</div>
</div>
<div class="product-content text-left">
<div class="product-title">
<h4>
{{ product.name|title }}
</h4>
</div>
<div class="product-price-wrapper">
<span>{{product.price}} TL</span>
</div>
</div>
</div>
</div>
{% endfor %}
{% endwith %}
</div>
<div class="row justify-content-end">
Daha Fazla...
</div>
{% endfor %}
My Model
Each product has a many-to-many relation with categories and products also have an is_available variable.
class ProductCategories(models.Model):
name = models.CharField(max_length = 60)
image = models.ImageField(upload_to = 'ProductCategories')
publish_date = models.DateTimeField(auto_now=False, auto_now_add=True)
is_available = models.BooleanField()
class Product(models.Model):
category = models.ManyToManyField(ProductCategories, related_name="product")
name = models.CharField(max_length = 60)
price = models.DecimalField(max_digits=65, decimal_places=2)
description = models.TextField()
publish_date = models.DateTimeField(auto_now=False, auto_now_add=True)
stock_number = models.IntegerField()
is_available = models.BooleanField()
My View
categories = ProductCategories.objects.all()
return render(request, 'shop/shopping.html', {'categories' : categories})
I am listing 4 products under each category but I would like to filter products that are available.
Should I filter products within view class and pass to template filtered product object separate Queryset or should I apply all filters within the template?
If I should filter them within the template as I tried above, is there any way to filter product objects according to their availability?
Thanks,
class ProductManager(models.Manager):
def is_available(self):
return self.get_queryset().filter(is_available=True)
class Product(models.Model):
--------
objects = ProductManager()
views.py
product = Product.objects.is_available()
return render(request, 'shop/shopping.html', {'products' : product})
templates
{% for product in products %}
{{ product.name }}
{% for item in product.category.all %}
{{ item.name }}
{% endfor %}{% endfor %}
Create a folder called "templatetags" at the same level as models.py and views.py in your application folder
Create a new file with the desired name in this folder. For example : 'app_tags.py'
Create a new file named __ init __.py in this folder
Open app_tags.py and write this code sample for create custom template filter:
from ..models import ProductCategories
from django import template
register = template.Library()
#register.filter
def is_available(value, arg):
products = value.filter(is_available = arg)
return products
And use like this in your Html:
{% load app_tags %}
...
...
...
{% with products=category.product.all|is_available:True %}
...
...
Please try this solution. I hope this helps to you.

How to filter foreign key in django filter

I want to get the username using the field user (foreignkey)
I don't know how get the username in the view
model.py
class Publication(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
filters.py
class PublicationFilter(django_filters.FilterSet):
user = django_filters.CharFilter(lookup_expr='exact')
class Meta:
model = Publication
fields = ['user']
views.py
def publication_list(request):
f = PublicationFilter(request.GET, queryset=Publication.objects.all())
return render(request, 'info/filter.html', {'filter':f})
html
<h2>Lista de sus informes</h2>
<p class="profile-data">
<div class="col-md-4 mt-2 mb-3 ">
<div class="row p-1">
<div class="col-md-12">
<form action="" method="get" >
<b> {{ filter.form.as_p }} </b><br>
<button type="submit">Search</button>
</form>
<ul>
<b>{% for profile in filter.qs %} </b><br>
<b>{{ profile.nombre }} </b><br>
<b>{{ profile.user }} </b><br>
Ver perfil<br>
{% endfor %}
You can use '__' : Publication.objects.filter(user__username="John Doe")

Categories

Resources