I want to make a button to filter product by category.. Example Salad or Meat. Without Model ProductAtribuut im able to do it, but now i added the model, so im real confused how i can get the data of a Foreign Key inside a Foreign Key
ProductAtribuut -> Product(FK) -> Categorie(FK)
Models.py
class Categorie(models.Model):
naam = models.CharField(max_length=150,db_index=True)
slug = models.SlugField(unique=True)
class MPTTMeta:
order_insertion_by = ['naam']
class Meta:
ordering=('-naam',)
def __str__(self):
return self.naam
def get_absolute_url(self):
return reverse('JavaKitchen:product_by_categorie', args=[self.slug])
#property
def get_products(self):
return Product.objects.filter(categorie__naam=self.naam)
class Groente(models.Model):
groente = models.CharField(max_length=100)
def __str__(self):
return self.groente
class Vlees(models.Model):
vlees = models.CharField(max_length=100)
def __str__(self):
return self.vlees
class Product(models.Model):
slug = models.SlugField(unique=True, primary_key=True)
titel = models.CharField(max_length=200)
beschrijving = models.TextField(blank=True, null=True)
categorie = models.ForeignKey(Categorie, on_delete=models.CASCADE)
class Meta:
ordering=('-titel',)
def __str__(self):
return self.titel
def get_title_uppercase(self):
return self.titel.upper()
def get_absolute_url(self):
return reverse('JavaKitchen:product_detail',args=[self.id,])
class ProductAtribuut(models.Model):
def groente():
return Groente.objects.filter(groente='geen').first()
def vlees():
return Vlees.objects.filter(vlees='geen').first()
product = models.ForeignKey(Product, on_delete=models.CASCADE, blank=False)
groente = models.ForeignKey(Groente, on_delete=models.CASCADE, default=groente)
vlees = models.ForeignKey(Vlees, on_delete=models.CASCADE, default=vlees)
prijs = models.FloatField(default=0)
afbeelding = models.ImageField(blank=True, upload_to='gerechten/') #later upgrade..
zichtbaar = models.BooleanField(default=True)
def __str__(self):
return self.product.titel
def image_tag(self):
return mark_safe('<img src="/media/%s" width="80" height="auto" />' % (self.afbeelding))
image_tag.short_description = 'Image'
Views.py
def product_list(request,categorie_slug=None):
categorie = None
javakitchen = JavaKitchen.objects.get(id=1)
openings_tijden = Openings_tijden.objects.all()
categories = Categorie.objects.all().filter(zichtbaar=True)
product = Product.objects.all()
productatribuut = ProductAtribuut.objects.all().filter(zichtbaar=True)
if categorie_slug:
categorie = get_object_or_404(Categorie,slug=categorie_slug)
product = productatribuut.filter(product=product)
context = { 'categories':categories,
'categorie':categorie,
'product':product,
'form':form,
'javakitchen':javakitchen,
'openings_tijden': openings_tijden,
'productatribuut': productatribuut
}
return render(request, 'pages/index.html', context)
HTML template
<div class="categories">
<h1>{% if categorie %}{{ categorie.naam }}{% else %} ALLE GERECHTEN {% endif %}</h1>
<ol class="type">
<li><a class="page-scroll" href='{% url "JavaKitchen:product_list" %}#dinner'>Alles</a></li>
{% for c in categories %}
<li><a class="page-scroll" href="{{ c.get_absolute_url }}#dinner">{{ c.naam }}</a></li>
{% endfor %}
</ol>
<div class="clearfix"></div>
</div>
I used this before to get the category. when i didnt have class ProductAtribuut
if categorie_slug:
categorie = get_object_or_404(Categorie,slug=categorie_slug)
product = product.filter(categorie=categorie)
but now i dont know how i do get the category
ProductAtribuut -> Product(fk) -> Categorie(fk)
Related
views.py
def product_display_detail(request, id, *args, **kwargs):
obj21 = Product.objects.filter(id=id).values()
obj3 =Stock.objects.filter(product_id=id).values()
obj1 =Product_type.objects.all()
context = {
"object21" : obj21,
"object1" : obj1,
"object3" : obj3
}
return render(request,"product_detail.html",context)
html file
{% for s in object3 %}
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input" id="size-1" name="size">
<label class="custom-control-label" for="size-1">{{ s.size_id.size_name }}</label>
</div>
{% endfor %}
models.py
class Size(models.Model):
size_name = models.CharField(max_length=20)
class Colour(models.Model):
col_name = models.CharField(max_length=40)
class Product(models.Model):
product_name = models.CharField(max_length=120)
product_type = models.ForeignKey(Product_type, null=False, on_delete=models.PROTECT)
product_desc = models.TextField(max_length=500 , blank=False)
product_price = models.DecimalField(max_digits = 5,decimal_places = 2)
product_qty = models.IntegerField()
product_image = models.ImageField(null=False,blank=False,upload_to="images/")
def __str__(self):
return self.product_name
class Stock(models.Model):
product_id = models.ForeignKey(Product, null=True,on_delete=models.CASCADE)
size_id = models.ForeignKey(Size, null=True,on_delete=models.CASCADE)
colour_id = models.ForeignKey(Colour,null=True,on_delete=models.CASCADE)
qty = models.IntegerField()
product_details = models.TextField(max_length=500 , null=True , blank=True)
image = models.ImageField(null=False,blank=False,upload_to="images/")
i want size name from size table using stock object
I use session's to create a shopping cart. I have a product model and a model for Product-sizes, which I define the size-title(XL , etc) and price of product in it . So that I can have products with different sizes as well as different prices. But my logic has some problems
if I add product_1 with size A , it's ok ...
if I add product_1 with size B , it's ok ...
but when I'm trying to add same product with different sizes at same time the cart only shows the price of first size
#shop/models.py
class ProductSizes(models.Model):
name = models.CharField(max_length=50)
price = models.IntegerField()
picture = models.ImageField(upload_to="products/%Y/%m/%d" )
class Product(models.Model):
name = models.CharField(max_length=100)
size = models.ManyToManyField(ProductSizes , blank=True , related_name="sizes" )
price = models.IntegerField()
#cart/cart.py
from django.conf import settings
from shop.models import Product
class Cart:
def __init__(self,request):
self.session = request.session
cart = self.session.get(settings.CART_SESSION_ID)
if not cart:
cart = self.session[settings.CART_SESSION_ID] = {}
self.cart = cart
# add to cart
def add(self,product,size_,quantity=1,override_quantity=False):
product_id = str(product.id)
print(product.size.name)
if product_id not in self.cart :
if size_ != None:
if size_.off_price:
self.cart[product_id] = {'quantity':0,'price':size_.off_price}
elif size_.price:
self.cart[product_id] = {'quantity':0,'price':size_.price}
else:
if product.off_price:
self.cart[product_id] = {'quantity':0,'price':product.off_price}
else:
self.cart[product_id] = {'quantity':0,'price':product.price}
if override_quantity:
self.cart[product_id]['quantity'] = quantity
else:
self.cart[product_id]['quantity'] += quantity
self.save()
def save(self):
self.session.modified = True
#remove from cart
def remove(self,product):
product_id = str(product.id)
if product_id in self.cart:
del self.cart[product_id]
self.save()
def __iter__(self):
product_ids = self.cart.keys()
products = Product.objects.filter(id__in=product_ids)
cart = self.cart.copy()
for product in products:
cart[str(product.id)]['product'] = product
for item in cart.values():
item['total_price'] = item['price'] * item['quantity']
yield item
def __len__(self):
return sum(item['quantity'] for item in self.cart.values())
def get_total_price(self):
return sum(item['price'] * item['quantity'] for item in self.cart.values())
def clear(self):
del self.session[settings.CART_SESSION_ID]
self.save()
ــــــــــــــــــ
from django.shortcuts import get_object_or_404 , redirect , render
from django.views.decorators.http import require_POST
from .cart import Cart
from shop.models import Product, ProductSizes
from .forms import CartAddProductForm
#require_POST
def cart_add(request , product_id , size):
cart = Cart(request)
product = Product.objects.get(id=product_id)
if size != 0:
size_ = product.size.get(id=size)
else:
size_ = None
form = CartAddProductForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
cart.add(product=product , quantity=cd['quantity'] ,size_=size_, override_quantity=cd['override'] )
return redirect("home")
#require_POST
def cart_remove(request , product_id):
cart = Cart(request)
product = get_object_or_404(Product,id=product_id)
cart.remove(product=product)
return redirect("cart.detail")
def cart_detail(request):
cart = Cart(request)
for item in cart:
item['update_quantity_form'] = CartAddProductForm(initial={
'quantity':item["quantity"],
"override":True,
})
return render(request , "cart.html" , {"cart":cart})
#cart/forms.py & urls
from django import forms
PRODUCT_QUANTITY_CHOICES = [(i , str(i)) for i in range(1,21)]
class CartAddProductForm(forms.Form):
quantity = forms.TypedChoiceField(choices=PRODUCT_QUANTITY_CHOICES,coerce=int)
override = forms.BooleanField(required=False, initial=False,widget=forms.HiddenInput)
---------------
urlpatterns = [
path("" , views.cart_detail , name="cart.detail"),
path("add/<int:product_id>/<int:size>/" , views.cart_add , name="cart.add"),
path("remove/<int:product_id>/" , views.cart_remove , name="cart.remove"),
]
#html
<div class="shopping-cart-wrap">
<span class="cart-total-amunt">{{cart.get_total_price}} تومان</span><i class="icon-shopping-bag2 float-left"></i><span class="cart-total">{{cart|length}}</span>
<ul class="mini-cart">
{% for item in cart %}
<li class="cart-item">
<div class="cart-image">
<img alt="" src="/media/{{item.product.picture}}" width="80" height="80">
</div>
<div class="cart-title">
<a href="single-product.html">
<h4>{{item.product.name}}</h4>
</a>
<div class="quanti-price-wrap">
<span class="quantity">{{item.quantity}} ×</span>
<div class="price-box"><span class="new-price">{{item.price}} تومان</span></div>
</div>
<a class="{% url 'cart.remove' item.product.id %}" href="#"><i class="icon-x"></i></a>
</div>
</li>
{% endfor %}
<li class="subtotal-box">
<div class="subtotal-title">
<h3>جمع کل :</h3><span>{{cart.get_total_price}} تومان</span>
</div>
</li>
<li class="mini-cart-btns">
<div class="cart-btns">
مشاهده سبد
پرداخت
</div>
</li>
</ul>
</div>
after 2 days of struggling finally I found the solution
for adding products with different sizes you have to pass the size model id to session instead of the product id
shop/models.py
class ProductSizes(models.Model):
name = models.CharField(max_length=50)
price = models.IntegerField()
off_price = models.IntegerField(blank=True , null=True)
picture = models.ImageField(upload_to="products/%Y/%m/%d" )
product = models.ForeignKey("Product" , on_delete=models.CASCADE )
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
picture = models.ImageField(upload_to="products/%Y/%m/%d" )
picture2 = models.ImageField(upload_to="products/%Y/%m/%d" , blank=True)
picture3 = models.ImageField(upload_to="products/%Y/%m/%d" , blank=True)
picture4 = models.ImageField(upload_to="products/%Y/%m/%d" , blank=True)
price = models.IntegerField()
available = models.BooleanField(default=True)
category = models.ForeignKey(Category ,on_delete=models.CASCADE , blank=True ,null=True )
slug = models.SlugField(max_length=100 , db_index=True , unique=True)
tags = TaggableManager(blank=True)
is_amazing = models.BooleanField(default=False)
amazing_till = models.CharField(max_length=10 , null=True , blank=True)
off_price = models.IntegerField(blank=True , null=True)
brand = models.ForeignKey(Brand ,on_delete=models.CASCADE , blank=True ,null=True )
created_at = models.DateField(auto_now_add=True)
update_at = models.DateField(auto_now=True)
def get_absolute_url(self):
return reverse('get.single.product', kwargs={'slug': self.slug})
class Meta:
ordering=("name",)
index_together = (('id' , 'slug'),)
cart/cart.py
from django.conf import settings
from shop.models import Product, ProductSizes
class Cart:
def __init__(self,request):
self.session = request.session
cart = self.session.get(settings.CART_SESSION_ID)
if not cart:
cart = self.session[settings.CART_SESSION_ID] = {}
self.cart = cart
# add to cart
def add(self,product,size_,quantity=1,override_quantity=False):
size_id = str(size_.id)
if size_id not in self.cart:
if size_.price:
self.cart[size_id] = {'quantity': 0, 'price': size_.price}
elif size_.off_price:
self.cart[size_id] = {'quantity': 0, 'price': size_.off_price}
self.cart[size_id]['quantity'] += quantity
self.save()
self.save()
def save(self):
self.session.modified = True
#remove from cart
def remove(self,size_):
product_id = str(size_.id)
if product_id in self.cart:
del self.cart[product_id]
self.save()
def __iter__(self):
sizes_ids = self.cart.keys()
products = ProductSizes.objects.filter(id__in=sizes_ids)
cart = self.cart.copy()
for size in products:
cart[str(size.id)]['size'] = size
for item in cart.values():
item['total_price'] = item['price'] * item['quantity']
yield item
def __len__(self):
return sum(item['quantity'] for item in self.cart.values())
def get_total_price(self):
return sum(item['price'] * item['quantity'] for item in self.cart.values())
def clear(self):
del self.session[settings.CART_SESSION_ID]
self.save()
cart/views.py
#require_POST
def cart_add(request , product_id , size):
cart = Cart(request)
product = Product.objects.get(id=product_id)
size_ = get_object_or_404(ProductSizes , id=size)
form = CartAddProductForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
cart.add(product=product , quantity=cd['quantity'] ,size_=size_, override_quantity=cd['override'] )
return redirect("home")
The template
{% block cart %}
<div class="shopping-cart-wrap">
<span class="cart-total-amunt">{{cart.get_total_price}} تومان</span><i class="icon-shopping-bag2 float-left"></i><span class="cart-total">{{cart|length}}</span>
<ul class="mini-cart">
{% for item in cart %}
<li class="cart-item">
<div class="cart-image">
<img alt="" src="/media/{{item.size.product.picture}}" width="80" height="80">
</div>
<div class="cart-title">
<a href="single-product.html">
<h4>{{item.size.name}}</h4>
</a>
<div class="quanti-price-wrap">
<span class="quantity">{{item.quantity}} ×</span>
<div class="price-box"><span class="new-price">{{item.price}} تومان</span></div>
</div>
<a class="{% url 'cart.remove' item.size.id %}" href="#"><i class="icon-x"></i></a>
</div>
</li>
{% endfor %}
<li class="subtotal-box">
<div class="subtotal-title">
<h3>جمع کل :</h3><span>{{cart.get_total_price}} تومان</span>
</div>
</li>
<li class="mini-cart-btns">
<div class="cart-btns">
مشاهده سبد
پرداخت
</div>
</li>
</ul>
</div>
{% endblock cart %}
my models:
class Aula(models.Model):
nome_aula = models.CharField(max_length=255)
descricao_aula = models.TextField()
...
def __str__(self):
return self.nome_aula
class Modulos(models.Model):
numero_modulo = models.CharField(default="Módulo 1",max_length=400)
aulas = models.ManyToManyField(Aula)
def __str__(self):
return self.numero_modulo
my views:
def aulasdomodulo(request, id):
mod = get_object_or_404(Modulos, pk=id)
aulas = mod.aulas.all()
return render(request, 'wtic/aulasdomodulo.html', {'aulas':aulas, 'mod':mod})
def conteudodaaula(request, id):
mod2 = get_object_or_404(Modulos, pk=id)
aula = mod2.aulas.all()
...
return render(request,'wtic/conteudo_aula.html', {'aula':aula})
my html where it shows the objects assigned that module accesses them
{% for aula in aulas %}
{{aula.nome_aula}}
Acessar
{% endfor %}
but when I try to access classes I get it
how can i access these objects one per page?
I wanna display the text value of a foreign key on the templante, in a way that the user cannot change it.
Template:
{% for form in formset %}
<div class="">
{% for field in form %}
{{ field }}
{% endfor %}
</div>
{% endfor %}
HTML render:
<select name="form-0-semestre_solicitacao" id="id_form-0-semestre_solicitacao">
<option value="">---------</option>
<option value="5">2020/1</option>
<option value="4">2019/2</option>
<option value="3" selected="">2019/1</option>
<option value="2">2018/2</option
<option value="1">2018/1</option>
</select>
I tried {{ field.initial }} and {{ field.value }} but it displays 3 and i would like it to display the text: 2019/1
Update:
The field in display refers to the Foreign Key in semestre_solicitacao
models.py
class Solicitacao(models.Model):
"""Solicitações, depende de User e curso"""
#TODO trocar homologada de boolean para choice homologada e não homologada, e ajustar forms
solicitante = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
disciplina = models.ForeignKey(Disciplina, on_delete=models.CASCADE)
justificativa = models.TextField(("Justificativa para o pedido"),
help_text="O candidato pode explicar os motivos para solicitar a prova, por exemplo: experiência profissional, cursos não regulares, aproveitamentos indeferidos, entre outros.", blank=True, null=True)
documentos = models.FileField(("Documentos comprobatorios de conhecimentos"),
upload_to=None, max_length=100, blank=True, null=True,
validators=[FileExtensionValidator(['.pdf'])])
data_solicitacao = models.DateTimeField(
("Data da solicitação"), auto_now_add=True)
cursou_anteriormente = models.BooleanField(
("Cursou anteriormente a disciplina solicitada"), blank=True, null=True)
homologada = models.BooleanField(blank=True, null=True)
semestre_solicitacao = models.ForeignKey(Calendario, on_delete=models.CASCADE, null=True)
Views.py
from extra_views import ModelFormSetView
class ItemFormSetView(ModelFormSetView):
model = Solicitacao
fields = ['semestre_solicitacao', 'solicitante', 'disciplina', 'cursou_anteriormente']
template_name = 'manage_solicitacoes.html'
success_url = reverse_lazy('cc:solicitacoes')
factory_kwargs = {'extra': 0}
def get_queryset(self):
slug = self.kwargs['slug']
return super(ItemFormSetView, self).get_queryset().filter(semestre_solicitacao__slug=slug)
I'm using django-extra-views.
Update 2:
I'm getting the top part of the image, and i would like something similar to the one in the bottom
Others Models:
class Calendario(models.Model):
"""Calendario referente as datas do semestre"""
ano = models.CharField(
("Ano"), max_length=4,
help_text='Ano dos pedidos, ex: 2020')
semestre = models.CharField(
("Semestre"), max_length=1,
help_text='Semestre dos pedidos')
is_active = models.BooleanField('Calendário em vigor', default=True)
inicio_solicitacoes = models.DateField(
"Inicío das Solicitações", auto_now=False, auto_now_add=False)
fim_solicitacoes = models.DateField(
"Fim das Solicitações", auto_now=False, auto_now_add=False)
inicio_recursos = models.DateField(
"Inicío dos Recursos", auto_now=False, auto_now_add=False)
fim_recursos = models.DateField(
"Fim dos Recursos", auto_now=False, auto_now_add=False)
slug = models.SlugField(unique=True)
class Meta():
ordering = ['-ano', '-semestre']
constraints = [
models.UniqueConstraint(
fields=['ano', 'semestre'], name='unique_ano_semestre')
]
def __str__(self):
return f'{self.ano}/{self.semestre}'
def get_absolute_url(self):
return reverse("calendario:calendario-detail", kwargs={"slug": self.slug})
def get_delete_url(self):
return reverse("calendario:calendario-delete", kwargs={"slug": self.slug})
def save(self, *args, **kwargs):
"""Garante que exista apenas um is_active=True e define a slug"""
slug_str = f'{self.ano}-{self.semestre}'
unique_slugify(self, slug_str)
if self.is_active:
with transaction.atomic():
Calendario.objects.filter(
is_active=True).update(is_active=False)
return super(Calendario, self).save(*args, **kwargs)
else:
return super(Calendario, self).save(*args, **kwargs)
def get_fields(self):
""" Permite usar for no template para exibir todos os atributos do objeto"""
return [(field.verbose_name, field.value_to_string(self)) for field in Calendario._meta.fields]
class Curso(models.Model):
"""Cursos existente e ativos com matriz"""
nome = models.CharField(max_length=30)
abreviacao = models.CharField(
'Abreviação', max_length=3, help_text='Máximo 3 letras')
matriz = models.CharField(
max_length=4, help_text='Ano de aprovação de matriz do curso')
is_active = models.BooleanField('Ativo', default=True)
slug = models.SlugField(max_length=20)
class Meta():
ordering = ['-is_active', 'nome']
def save(self, *args, **kwargs):
slug_str = self.abreviacao + self.matriz
unique_slugify(self, slug_str)
self.abreviacao = self.abreviacao.upper()
super(Curso, self).save(*args, **kwargs)
def __str__(self):
return f'{self.abreviacao}/{self.matriz}'
def get_absolute_url(self):
return reverse("curso:curso-detail", kwargs={"slug": self.slug})
class Disciplina(models.Model):
"""Modelo disciplina"""
codigo = models.CharField(("Código"), max_length=12, primary_key=True, unique=True)
nome = models.CharField(("Nome da disciplina"), max_length=50)
curso = models.ManyToManyField('Curso')
def __str__(self):
return f'{self.codigo} - {self.nome}'
def get_absolute_url(self):
"""Url para o template com detalhes de uma disciplinas especifica"""
return reverse("curso:disciplina-detail", kwargs={"pk": self.codigo})
{{ form.instance.solicitante }} e {{ form.instance.solicitante.curso }}
Did what i wanted
I'm trying to display a manytomany field in my template, but all I get is a blank...I'm displaying it as below:
{% for vehicle in vehicle.features.features %}
<li>vehicle.features</li>
{% endfor %}
My model is as follows:
class Vehicle(models.Model):
stock_number = models.CharField(max_length=6, blank=False)
vin = models.CharField(max_length=17, blank=False)
common_vehicle = models.ForeignKey(CommonVehicle)
exterior_colour = models.ForeignKey(ExteriorColour)
interior_colour = models.ForeignKey(InteriorColour)
interior_type = models.ForeignKey(InteriorType)
odometer_unit = models.ForeignKey(OdometerUnit)
status = models.ForeignKey(Status)
odometer_reading = models.PositiveIntegerField()
selling_price = models.PositiveIntegerField()
purchase_date = models.DateField()
sales_description = models.CharField(max_length=60, blank=False)
feature_sets = models.ManyToManyField(FeatureSet, blank=True)
features = models.ManyToManyField(Feature, blank=True)
def __unicode__(self):
return self.stock_number
The classes I'm linking to are:
class Feature(models.Model):
name = models.CharField(max_length=32)
type = models.ForeignKey(FeatureType)
def __unicode__(self):
return self.name
class FeatureSet(models.Model):
name = models.CharField(max_length=12)
features = models.ManyToManyField(Feature)
def __unicode__(self):
return self.name
Use this:
{% for feature in vehicle.features.all %}
<li>{{ feature }}</li>
{% endfor %}