Working on an application were I have a One to Many relationship where I have many Products and a few particular products will be related to only one Website.
On my Home page is where I display my listed sites from my Website Model I would like to show products for when the user clicks on anyone of the slugs on my Homepage the are redirected to go into a product page ( another template ) where I have all of the objects related from my Product Model to that particular website to display only.
Here is a User flow of my situation
Homepage --> click on website ('/browse/website_slug') ---> Go To --> Product page (filled with only Product Objects from related clicked slug)
Models.py in my product_extend app
Product Model:
class Product(models.Model):
"""
The product structure for the application, the products we scrap from sites will model this and save directly into the tables.
"""
product_name = models.CharField(max_length=254, verbose_name=_('Name'), null=True, blank=True)
product_price = CurrencyField( verbose_name=_('Unit price') )
product_slug_url = models.URLField(max_length=200, null=True, blank=True)
product_category = models.CharField(max_length=254, blank=True, null=True)
product_img = models.ImageField('Product Image', upload_to='product_images', null=True, blank=True)
product_website_url = models.URLField(max_length=200, null=True, blank=True)
product_website_name = models.CharField(max_length=254, blank=True, null=True)
#For Admin Purposes, to keep track of new and old items in the database by administrative users
date_added = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date added'))
last_modified = models.DateTimeField(auto_now=True, null=True, blank=True, verbose_name=_('Last modified') )
#For Admin Purposes, to make sure an item is active by administrative users
active = models.BooleanField(default=True, verbose_name=_('Active') )
# Foreign Key
website = models.ForeignKey(Website, null=True, related_name='website_to_product')
Website Model
class Website(models.Model):
name = models.CharField(max_length=254, blank=True, null=True, unique=True)
description = models.TextField(null=True, blank=True)
website_slug = models.SlugField(verbose_name=_('Website Slug'), unique=True)
site_logo = models.ImageField('Websites Logo', upload_to='website_logo_images', null=True, blank=True)
menswear = models.BooleanField(default=False, verbose_name=_('Menswear'))
womenswear = models.BooleanField(default=False, verbose_name=_('Womenswear'))
active = models.BooleanField(default=True, verbose_name=_('Active'))
Views in my product_extend app
view.py
class ProductView(ListView):
context_object_name = 'product_list'
template_name = 'product_extend/_productlist.html'
# queryset = ProductExtend.objects.filter(id=1)
model = Product
def get_context_data(self, **kwargs):
context = super(ProductView, self).get_context_data(**kwargs)
return context
class WebsiteView(ListView):
context_object_name = 'home'
template_name = 'homepage.html'
queryset = Website.objects.order_by('name')
model = Website
def get_context_data(self, **kwargs):
context = super(WebsiteView, self).get_context_data(**kwargs)
return context
Templates
Homepage.html
{% for object in home %}
<li class="page_tiles-home home-website-reveal">
<a href="browse/website_slug" data-title="{{object.name}}" data-description="{{object.description}}">
<img alt="{{object.name}}" src="{{MEDIA_URL}}{{object.site_logo}}" />
</a>
</li>
{% endfor %}
Product.html
{% for object in product_list %}
<li class="col n-4">
<figure class="rollover site">
<div class="scrap-likes"><span class="icon-heart"></span></div>
<img src="{{object.product_img}}" width="470" height="700">
<!-- <div class="scrap-from"> Scrapped from:<a class="scrap-site" target="_blank" href="{{object.product_website_url}}">{{object.product_website_name}}</a></div> -->
<div class="scrap-designer"> Scrapped from: <a class="scrap-site" target="_blank" href="{{object.product_website_url}}">{{object.product_website_name}}</a></div>
<div class="scrap-title">{{object.product_name }}, <span class="scrap-price">${{object.product_price}}</span></div>
<a class="scrap-buy" target="_blank" href="{{object.product_slug_url}}">View Item</a>
</figure>
</li>
{% endfor %}
Urls
my apps urls.py
urlpatterns = patterns('',
url(r"^$", WebsiteView.as_view(), name="home"),
url(r'^browse/', include('product_extend.urls')),
)
my apps product_extend urls.py
urlpatterns = patterns('',
??? No clue what to put ???
)
You can add this in product_extend urls.py:
urlpatterns = patterns('',
url(r'^(?P<website_slug>[\w]+)$', ProductView.as_view(), name='products_list'),
)
Then in ProductView override the get_queryset method to use the website_slug for filtering the queryset:
class ProductView(ListView):
context_object_name = 'product_list'
template_name = 'product_extend/_productlist.html'
# queryset = ProductExtend.objects.filter(id=1)
model = Product
def get_context_data(self, **kwargs):
context = super(ProductView, self).get_context_data(**kwargs)
return context
def get_queryset(self):
qs = super(ProductView, self).get_queryset()
return qs.filter(website__website_slug__exact=self.kwargs['website_slug'])
after reading twice, think what you want is:
url(r'^product/website/(?P<slug>)$', "your_view_to_peform_product_search_for_slug_website_here"),
and in your view "HTML"
href="product/website/{{ website.slug }}"
something like this...
Related
I'm working on a questionnaire and I made a page where user have a list of which questionnaires to fill and which did he filled before but I have stucked.
I like to check if the user filled a form/questionnaire before and if he didn't show him the questionnaire link.
My solutions doesn't work because it checks the db just if the user filled the questionnaire but if he did not (no row for him in the db) it shows a blank cell in my table.
(I don't know if exists query could be a solution but I can't made it work)
main.html
{% for i in oke_vezetoi %}
{% if i.vezetoi_ok == True %}
<td><button class="btn btn-sm btn-outline-info"> Kitöltöm</button>
<td><i class="fas fa-running fa-2x text-dark"></i></td>
{% else %}
<td class="text-success text-uppercase">Kitöltötted</button>
<td><i class="fas fa-check fa-2x text-success"></i></td>
{% endif %}
{% endfor %}
views.py
def main(request):
oke_vezetoi = Vezetoi.objects.filter(user_name=request.user)
oke_stressz = Stressz_teszt.objects.filter(user_name=request.user)
context = {
'oke_vezetoi': oke_vezetoi,
'oke_stressz': oke_stressz,
}
return render(request, 'stressz/main.html', context)
models.py
class Vezetoi(models.Model):
def __str__(self):
return str(self.user_name)
user_name = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
vezetoi_v01 = models.IntegerField( null=True)
vezetoi_v02 = models.IntegerField( null=True)
vezetoi_v03 = models.IntegerField( null=True)
vezetoi_v04 = models.IntegerField( null=True)
vezetoi_v05 = models.IntegerField( null=True)
vezetoi_v06 = models.IntegerField( null=True)
vezetoi_v07 = models.IntegerField( null=True)
vezetoi_v08 = models.IntegerField( null=True)
vezetoi_v09 = models.IntegerField( null=True)
vezetoi_v10 = models.IntegerField( null=True)
vezetoi_v11 = models.IntegerField( null=True)
vezetoi_v12 = models.IntegerField( null=True)
vezetoi_ok = models.BooleanField()
forms.py
class VezetoiForm(forms.ModelForm):
class Meta:
model = Vezetoi
fields = ['vezetoi_v01', 'vezetoi_v02', 'vezetoi_v03', 'vezetoi_v04', 'vezetoi_v05', 'vezetoi_v06', 'vezetoi_v07', 'vezetoi_v08', 'vezetoi_v09', 'vezetoi_v10', 'vezetoi_v11', 'vezetoi_v12', 'vezetoi_ok' ]
I'm not sure if I'm interpreting your question correctly, but it seems like there are a few things that you could optimise.
It sounds like there should only be one entry per user in the Vezetoi model.
If this is true, you should enforce ForeignKey(unique=True), and you don't need a for loop and you can use Vezetoi.objects.get() in your views.py
If this is not true, and there are multiple Vezetoi integers per user, you might want to have one Vezetoi object for each integer.
If the user hasn't submitted a questionnaire, then the Vezetoi model object will not exist.
Since the object doesn't exist, it won't appear in the oke_vezetoi queryset, so the object attribute i.vezetoi_ok will not be found in your loop (this is why your table row is blank).
Assuming the field vezetoi_ok is only intended to check for the existence of the questionnaire, it can only ever be True, so you can remove it from the model definition.
If these are not true, I'll need to amend the answer and I'll ask you to provide more information about what these models are tracking, the content of the Stressz_teszt model and urls.py as well as how the VezetoiForm is implemented.
So in the case that I've described, I'd do it like this with a class based view and the get_context_data method.
models.py
class Vezetoi(models.Model):
def __str__(self):
return str(self.user_name)
user_name = models.ForeignKey(User, on_delete=models.CASCADE, unique=True)
vezetoi_v01 = models.IntegerField(null=True)
...
# vezetoi_ok = models.BooleanField()
forms.py
class VezetoiForm(forms.ModelForm):
class Meta:
model = Vezetoi
fields = '__all__'
views.py
class MainView(TemplateView):
template_name = 'main.html'
def get_context_data(self, **kwargs):
context = super().get_context_data()
context['oke_vezetoi'] = Vezetoi.objects.get(user_name=request.user)
context['oke_stressz'] = Stressz_teszt.objects.get(user_name=request.user)
return context
main.html
{% extends 'base.html' %}
{% if oke_vezetoi %}
{# do not display link #}
{% else %}
{# display link #}
{% endif %}
I am developing an ecommerce website with Django. In my home page displayed product cards as you see in the below image.
This product image in each card I take from my Product model (image field). When I hover over this image on the home page, the image is changing to another image. That is for I need another image, and I want to take the next image (display when I hover over) from my Product_images model. But I don't know how to do that.
urls.py
from django.urls import path
from . import views
from django.conf.urls.static import static
urlpatterns =
path('', views.home_page, name='amd-home'),
path('product/<int:id>/', views.product_detail, name='product-detail'),
path('about/', views.about, name='amd-about'),
]
views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView
from django.http import HttpResponse
from .models import Product, Product_image, Product_details
def home_page(request):
products = Product.objects.all()
images = Product_image.objects.all()
context = {'products':products, 'images':images}
return render(request, 'product/home.html', context)
models.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=200)
parent_id = models.IntegerField(default=0)
description = models.TextField()
image = models.ImageField(upload_to='uploads/')
def __str__(self):
return f'{self.name}'
class Brand(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=400)
image = models.ImageField(upload_to='uploads/')
def __str__(self):
return f'{self.name}'
class Product(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(upload_to='uploads/', blank=True, null=True)
sku = models.CharField(max_length=200)
price = models.IntegerField(default=0)
price_old = models.IntegerField(default=0)
description = models.TextField()
status = models.BooleanField(default=False)
date_posted = models.DateTimeField(auto_now_add=True)
internal_storage = models.CharField(max_length=50, blank=True, null=True, default=None)
ram = models.CharField(max_length=50, blank=True, null=True, default=None)
user = models.ForeignKey(User, on_delete=models.CASCADE)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return f'{self.title}, {self.description}'
class Product_image(models.Model):
image = models.ImageField(upload_to='uploads/')
product = models.ForeignKey(Product, on_delete=models.CASCADE)
def __str__(self):
return f'{self.product.title} image'
home.html
my template file is a very large file, so I only insert the element where I get an image from the Product model (this code word fine), but I don't know how to write code to take images from my Product_image model.
{% for product in products %}
<img alt="" src="{{ product.image.url }}">
{% endfor %}
First, in your model you can give a related_name field like :
class Product_image(models.Model):
image = models.ImageField(upload_to='uploads/')
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="product_images)
def __str__(self):
return f'{self.product.title} image'
Then you can access the product's images in template like:
{% for product in products %}
{% for image in product.product_images.all %}
<img alt="" src="{{ image.image.url }}">
{% endfor %}
{% endfor %}
PS: You dont have to return all Product_image quesryset from the view
Expanding on the answer, if you want to order the images there are different approaches you can take:
Method1:
class Product_image(models.Model):
image = models.ImageField(upload_to='uploads/')
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="product_images)
time_created = models.DateTimeField(null=True, blank=True)
def __str__(self):
return f'{self.product.title} image'
class Meta:
ordering = ['time_created']
This will order the query set from first created to last . If you don't want to add a time created field you can also choose to order by id.
Method2:
Add a property to your Product model:
class Product:
....
#property
def sorted_image_set(self):
return self.product_images.order_by('time_created')
Then you can access this property from the template
{% for image in product.sorted_image_set %}
Method 3 :
Creating a custom template tag to support order_by in template
#register.filter
def order_by(queryset, args):
args = [x.strip() for x in args.split(',')]
return queryset.order_by(*args)
Then you can do :
{% for image in product.product_images|order_by:"time_created" %}
After the list has been ordered you can access it just by the array indexes like for example images[0] or images[1]
change src in your HTML
{% for product in products %}
<a href="{% url 'product-detail' product.id %}"><img alt="" src="/media/uploads/{{
product.image }}"></a>
{% endfor %}
I have assumed that you have MEDIA_URL=/media/ in your settings. Change this in src if you have different MEDIA_URL
Guys i am new to Django but i am bit clued up on a few things. I need help with urls. So in my models.py i defined category, subcategory and product models and all these models fields have got a slugfield. I have also managed to define the index page url and its working but after the index page i want when the user clicks the category link he will be able to see subcategories that are under categories, and when the user click on subcategories he will able to see products in the subcategory. So for example i would love to create an url like www.127.0000/electronics , electronics is the category and under electronics the user will be able to see subcategories like TV's , Microwaves...when the user click on TV's link the url will be www.127.0000/electronics/tvs and at this page the user will see the products. This is my models.py
class Category(models.Model):
name= models.CharField(max_length=100)
slug= models.SlugField(max_length= 100, unique= True)
class Meta:
ordering = ('name',)
verbose_name= 'category'
verbose_name_plural= 'categories'
def __str__(self):
return self.name
class SubCategory (models.Model):
name = models.CharField(max_length= 200)
slug = models.SlugField (max_length= 200, unique= True)
category= models.ForeignKey(Category, on_delete= models.CASCADE)
class Meta:
ordering = ('name',)
verbose_name= "SubCategory"
verbose_name_plural= 'SubCategories'
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(max_length=250)
price = models.DecimalField(max_digits=10 , decimal_places=2)
image = models.ImageField(max_length=20, blank= True)
subcategory = models.ForeignKey(SubCategory, on_delete= models.CASCADE)
class Meta:
ordering = ('name',)
verbose_name= 'product'
verbose_name_plural = 'products'
def __str__(self):
return self.name
and this is my app urls
urlpatterns= [
path('', views.index, name='Index'),
path('<slug:category_slug>/', views.category, name= 'Categories' )
views.py file
def index (request):
""""Defines homepage"""
return render (request, 'index.html')
def category (request, category_slug):
"""Defines categories slug"""
categories= get_object_or_404(Category, slug=category_slug)
context= {'categories': categories}
return render (request, 'category.html', context}
this is my category html gile
{% extends 'base.html' %}
{% block content %}
<p>
<ul>
{% for category in categories %}
<li> {{category}} </li>
{% empty %}
<li> No Category has been added yet</li>
{% endfor %}
</ul>
</p>
{% endblock content %}
Could you please guide in the right direction so that when i click on www.127.0000/clothes i see the subcategories in clothes and the i click on and subcategories the url will change to maybe 127.000/clothes/men clothes and display the products in men clothes subcategory.
am working on a Django project where showing the details of post and amount
here is my models.py of post
class Loader_post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE ,related_name="Loader")
pick_up_station = models.CharField(max_length=150)
destination_station = models.CharField(max_length=150)
sender_name = models.CharField(max_length=150)
phone_number = PhoneNumberField(null=False, blank=False, unique=True)
receiver_name = models.CharField(max_length=150)
def __str__(self):
return self.user.username
def get_absolute_url(self):
return reverse("Loader:my_job", kwargs={"pk": self.pk})
this is my second models which I inherit Loader post
class price(models.Model):
my_post = models.ForeignKey(Loader_post, related_name='prices',on_delete=models.CASCADE,
null=True, default='')
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, null=True, default='')
driver_price = models.CharField(max_length=150, null=True)
driver_name = models.CharField(max_length=150, null=True)
approved_price = models.BooleanField(default=False)
status = models.BooleanField(default=False)
def get_absolute_url(self):
return reverse("Driver:Driverview")
def __str__(self):
return self.driver_price
this is the view.py of both list and details view
class offer_view(ListView, SelectRelatedMixin):
context_object_name = 'offern'
model = Loader_post
template_name = "offer.html"
def get_queryset(self):
qs = Loader_post.objects.filter(user=self.request.user)
return qs
class offer_view_detail(DetailView):
context_object_name = 'offernew'
model = Loader_post
template_name = "offer_detail.html"
here is my HTML page of list view ...when someone clicks on it it shows the detail of next post
offer.html
{% for my in offern %}
{{my.sender_name}} {% endfor %}
and when someone clicks on its route to the detail page .. but it shows template doesn't exist
this is my detail page ie. offer_details.hml
<p>{{offernew.sender_name}}</p>
<p>{{offernew.receiver_name}}</p>
{% for x in offernew.prices.all %}
<p>
<p>{{x.driver_name}}</p>
</p>
and this is urls.py
path('offerdetail/<int:pk>', views.offer_view_detail.as_view(),name="offerdetail"),
path('offer/', views.offer_view.as_view(), name="offer"),
Following on from comments,
In you ListView,
{{my.sender_name}}
here, the url specified is not defined in your urls.py, that's why it was showing no template doesn't exist, changing to this would solve this.
{{my.sender_name}}
Now, To show prices model in your DetailView, i would do something like this.
class offer_view_detail(DetailView):
context_object_name='offernew'
model = Loader_post
template_name = "offer_detail.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['price_model'] = self.object.prices.all()
return context
and In your Template
<p>{{offernew.sender_name}}</p>
<p>{{offernew.receiver_name}}</p>
{% for x in offernew.price_model %}
<p>{{x.driver_name}}</p>
{% endfor %}
Django Docs for DetailView
I'm new to django; I'm unable to display current login user details on profile template from model. When I will try with Maas.objects.all(), I get all existing user's data also. I need to display only the current login user data on template. When I try with Maas.objects.get(username=username), I get an error
Type error: Maas.testapp.models doesn't exist match query
My views.py:
def maas(request,maas_username_slug):
context_dict = {}
try:
maas = Maas.objects.get(slug=maas_username_slug)
context_dict['maas_username'] = maas.username
context_dict['maas_username_slug'] = maas_username_slug
context_dict['maas_phone'] = maas.phone
context_dict['maas_firstname'] = maas.firstname
context_dict['maas_lastname'] = maas.lastname
context_dict['maas_location'] = maas.location
context_dict['date_of_birth'] = maas.date_of_birth
context_dict['comments'] = maas.comments
context_dict['maas_gender'] = maas.gender
context_dict['photo'] = maas.photo
context_dict['maas'] = maas
except Maas.DoesNotExist:
pass
print(context_dict)
return render(request, 'testapp/profile.html', context_dict)
My profile.html:
<!DOCTYPE html>
{%extends 'testapp/base.html'%}
{%block body_block%}
<h1>Profile page</h1>
<h1>{{ maas_username }}</h1>
<li>Phone: {{ maas_phone }} </li>
<li>firstname: {{ maas_firstname }} </li>
<li>lastname: {{ maas_lastname }} </li>
<li> gender: {{ maas_gender }} </li>
<li> Comments: {{ comments }} </li>
{%endblock%}
My models.py:
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
class Maas(models.Model):
username=models.CharField(max_length=25)
password = models.CharField(max_length=50)
phone = models.IntegerField(default=0)
firstname = models.CharField(max_length=40, blank=True)
lastname = models.CharField(max_length=40, blank=True)
location = models.CharField(max_length=40, blank=True)
email = models.EmailField(blank=True)
date_of_birth = models.DateField(null=True, blank=True)
gender = models.CharField(max_length=10, blank=True)
comments = models.CharField(max_length=500, blank=True)
photo = models.ImageField(upload_to='media/photos/', null=True,
blank=True)
slug = models.SlugField(unique=True,default="")
def __str__(self):
return self.username
def save(self, *args, **kwargs):
self.slug = slugify(self.username)
super(Maas, self).save(*args, **kwargs)
def __unicode__(self):
return self.username
class UserProfile(models.Model):
user = models.OneToOneField(User)
nickname = models.CharField(max_length=20, blank=True)
def __unicode__(self):
return self.user.username
My urls.py
urlpatterns = [
url(r'(?P<maas_username_slug>\w+)/$', views.maas,
name='profile'),
]
Not getting any error but not displaying data on profile.html