how to load same models section in two diffrent pages - django

i have a model name section connected with other model name subject with foreign key what i want to do is i want to load half of it content in other page and half of it content on other html
my models.py
class Section(models.Model):
subject = models.ForeignKey(Subject, on_delete=models.CASCADE, related_name='section')
sub_section = models.CharField(max_length=500, blank=True)
title = models.CharField(max_length=5000, blank=False)
teacher = models.CharField(max_length=500, blank=False)
file = models.FileField(upload_to='section_vedios', blank=False)
about_section = models.TextField(blank=False, default=None)
price = models.FloatField(blank=False)
content_duration = models.DurationField(blank=False)
joined_date = models.DateTimeField(default=timezone.now,editable=False)
update_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.subject.name
i mean i want to load {{section.title }} in one page and {{section.file }} on other when a person
click on the {{ section.title }}
here is my html
<ul>
{% for section in section_list %}
<div class="card">
<div class="card-header">
{{ subject.name}}
</div>
<div class="card-body">
<h5 class="card-title">{{ section.title }}</h5>
<p class="card-text"></p>
CLick Here
</div>
</div>
{% endfor %}
so when a person click on click here a another load up and in that i want to load another html and in that file load only related {{section.file.url}} will open up

if you want 2 pages, easy way is create generic view in views.py and write in class Section:
paginate_by = 2
this is complete tutorial:
https://docs.djangoproject.com/en/3.2/topics/pagination/#paginating-a-listview

Related

Model Relationship django

I'd appreciate your help. I have two models. In the Bids model you will find current_bid_cmp. I would like from the ListingAuctions model to be able to access the corresponding current_bid_cmp of the Bids model. I only have found information to do querys from the model which contains the foreingKey.
My view: I use get_context_data because I have been trying anothers querys. perhaps its not the more aproppiate
class index(ListView):
model = ListingAuctions
template_name = "auctions/index.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['object'] = ListingAuctions.objects.all()
return context
My Models:
class ListingAuctions(BaseModel):
title_auction = models.CharField('Title of the auction',max_length = 150, unique = True)
description = models.TextField('Description')
user = models.ForeignKey(User, on_delete = models.CASCADE)
category = models.ForeignKey(Category, on_delete = models.CASCADE)
initial_bid = models.FloatField(default=False)
content = models.TextField('Content of auction')
image = models.ImageField('Referential Image', null=True,
upload_to = 'images_auctions', max_length = 255, default= 'noimage.png')
class Bids(BaseModel):
user = models.ForeignKey(User, on_delete = models.CASCADE, related_name='offer_user')
listing_auctions = models.ForeignKey(ListingAuctions,null=True, on_delete= models.CASCADE, related_name='l_auctions')
initialized_bid = models.BooleanField(default=False)
current_bid_cmp = models.FloatField('Current Bid Cmp',blank=True, null=True )
offer = models.FloatField(default=0 ,null=True, blank=True)
My HTML Current bid: $ {{post.l_auctions.current_bid_cmp}} its my attemp l_auctions is the relate name from listing_auctions in Bids model. Post is a ListingAuction object:
{% for post in object_list %}
<div class=" col-md-4 mt-4 ">
<div class="card " style="width: 18rem;">
<a href="{% url 'auctions_detail' post.pk %}">
<img class="card-img-top img-fluid" src="{{ post.image.url }}" alt="Card image cap" >
</a>
<div class="card-body">
<a class="darklink" href="{% url 'auctions_detail' post.pk %}"> <h5 class="card-title">{{post.title_auction}}</h5></a>
<h5>Starting bid: $ {{post.initial_bid}}</h5>
<h5>Current bid: $ {{post.l_auctions.current_bid_cmp}}</h5>
<p class="card-text">{{post.content | truncatechars:700 }}</p>
Show Auction
</div>
</div>
</div>
{% endfor %}
Try this in your template:
{{ post.l_auctions.get.current_bid_cmp }}
Update
I modified your models a bit so they make more sense to me. You might need your BaseModel for a good reason so feel free to modify to your needs. I also changed some names. There's still things I see that don't make a lot of sense in them but I'll leave that to you.
models.py
from django.db import models
from django.conf import settings
class BaseModel(models.Model):
pass
class Category(models.Model):
name = models.CharField(max_length=20)
class Listing(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
title = models.CharField('Title of the auction', max_length=150, unique=True)
description = models.TextField('Description')
starting_bid = models.FloatField(default=False)
content = models.TextField('Content of auction')
image = models.ImageField('Referential Image', null=True,
upload_to='images_auctions', max_length=255, default='noimage.png')
def __str__(self):
return self.title
class Bid(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='offer_user')
listing = models.ForeignKey(Listing, null=True, on_delete=models.CASCADE, related_name='bids')
initialized_bid = models.BooleanField(default=False)
amount = models.FloatField('Current Bid', blank=True, null=True)
offer = models.FloatField(default=0, null=True, blank=True)
def __str__(self):
return str(self.amount)
class Meta:
get_latest_by = 'amount'
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for listing in object_list %}
<div class=" col-md-4 mt-4 ">
<div class="card " style="width: 18rem;">
<a href="#">
<img class="card-img-top img-fluid" src="{{ listing.image.url }}" alt="Card image cap">
</a>
<div class="card-body">
<a class="darklink" href="#">
<h5 class="card-title">{{ listing.title }}</h5></a>
<h5>Starting bid: $ {{ listing.starting_bid }}</h5>
<h5>Current bid: $ {{ listing.bids.latest }}</h5>
<p class="card-text">{{ listing.content | truncatechars:700 }}</p>
Show Auction
</div>
</div>
</div>
{% endfor %}
</body>
</html>
Here's an interactive session from a shell:
from django.contrib.auth import get_user_model
User = get_user_model()
admin = User.objects.get_or_create(username='admin')[0]
steve = User.objects.get_or_create(username='steve')[0]
jenny = User.objects.get_or_create(username='jenny')[0]
almond = User.objects.get_or_create(username='almond')[0]
from auctions.models import Category, Listing, Bid
c = Category.objects.get_or_create(name='General')[0]
l1 = Listing.objects.get_or_create(user=admin, category=c, title='Some title', description='description', starting_bid=1.00, content='content')[0]
b1 = Bid.objects.get_or_create(user=steve, listing=l1, amount=1.00)[0]
b2 = Bid.objects.get_or_create(user=jenny, listing=l1, amount=1.01)[0]
b3 = Bid.objects.get_or_create(user=almond, listing=l1, amount=1.02)[0]
>>> l1.bids.all()
<QuerySet [<Bid: 1.0>, <Bid: 1.01>, <Bid: 1.02>]>
You could get the max by:
Adding this to your class:
class Meta:
get_latest_by = 'amount'
and using listing.bids.latest()...
Or using aggregate:
from django.db.models import Max
>>> l1.bids.aggregate(max=Max('amount'))
{'max': 1.02}
The key thing to note is, listing.bids returns a "RelatedManager". This just means you can use familiar queryset methods like .all(), .get(), .filter(), .last(), .latest(), etc. Many more.
In your case, you should first review this article on how to get the max of a queryset. Then decide how you want to proceed. In the example above, I put a class Meta on the Bid model which lets you get the latest object back based on the amount. This assumes the latest amount is always the highest, which might not be true for your situation.
One other thing you could do is add a #property to your Listing model.
class Listing(models.Model):
...
#property
def max_bid(self):
from django.db.models import Max
max_bid = self.bids.aggregate(max=Max('amount'))
if max_bid.get('max'):
return max_bid['max']
return ""
Use in your template like this:
<h5>Current bid: $ {{ listing.max_bid }}</h5>
Use in your Jinja Template
{{object_list.0.l_auctions.current_bid_cmp}}

How can show categories products in home page?

I want to show my all products row by row on the home page category-wise. Suppose, before starting a new row will have a heading(category name) and then will show all products according to the product category and then again will be starting a new row with a heading according to category. How can I do it? I applied the 3/4 methods but didn't work. Bellow, I've shown one of the methods. It doesn't work properly. Please help me.
views.py:
def home(request):
all_products = Products.objects.all()
context ={
"all_products":all_products,
}
return render(request,'home.html', context)
model.py:
class Category(models.Model):
title = models.CharField(blank=True, null=True, max_length = 100)
def __str__(self):
return str(self.title)
class Products(models.Model):
product_image = models.ImageField(blank=True, null=True, upload_to = "1_products_img")
product_title = models.CharField(blank=True, null=True, max_length = 250)
product_price = models.IntegerField(blank=True, null=True)
offer_price = models.IntegerField(blank=True, null=True)
created_date = models.DateTimeField(blank=True, null=True, auto_now=True)
product_category = models.ForeignKey(Category, related_name="categoty_related_name", on_delete=models.CASCADE, blank=True, null=True)
context_processors.py:
from .models import Category
def categories(request):
return {"categories":Category.objects.all()}
template:
{% for products in all_products %}
<h4 class="text-start montserrat_alternates_font ">{{products.product_category}}</h4>
<hr>
<!--- product card --->
<div class="col mb-5">
<div class="card h-100">
<!-- Sale badge-->
{% if products.offer_price != None %}
<div class="badge bg-dark text-white position-absolute" style="top: 0.5rem; right: 0.5rem">
SALE
</div>
{% endif %}
<!-- Product image-->
<img class="card-img-top" style="height:150px;" src="{{products.product_image.url}}" alt="..." />
<!-- Product details-->
<div class="card-body ">
<div class="text-center">
<!-- Product name-->
<h5 class="fw-bolder product_title" style="">{{products.product_title}}</h5>
</div>
</div>
</div>
</div>
{% endfor %}
You have to change your thinking a bit :)
The easiest approach is to think from bigger "items" (like your Category) to smaller (Product).
Firstfully, use singular naming for models, like Product (without 's', just like you did with Category), because otherwise you will end up with confusing setting. Also, don't name fields with your model's name unless it's really necessary, product_category should be simply category and so on.
Secondly, open big for loop with Category that you pass as classic view's context:
def home(request):
categories = Category.objects.all()
context = {
"categories": categories,
}
return render(request,'home.html', context)
Then look at your ForeignKey field in Product:
class Products(models.Model):
...
category = models.ForeignKey(Category, related_name="products", ...)
The key is to use related name properly. In your template, try logic like this (using related_name smoothly in reversed relationship):
{% for category in categories %}
{{ category.title }}
{% for product in category.products.all %}
{{ product.title }} - {{ product.price }}
{% endfor %}
{% endfor %}
If you don't set related_name, then it would be accessible with <model_name>_set.all(), in this case product_set.all() (in templates without brackets, of course). Anyway, it will work like a charm :)

Django: How do I access a related object max value in html template

I am attempting to display a list of items for auction. For each item, I am wanting to also display the current bid price. The current bid price should be the max value or last added to the Bids class for each individual listing.
How do I render in my HTML the max Bid.bid_price for each item in my Listing.objects.all() collection?
Below are my models, views, and HTML.
Models:
class Listing(models.Model):
title = models.CharField(max_length=65, default="")
description = models.CharField(max_length=200, default="")
category = models.CharField(max_length=65, default="")
image = models.ImageField(blank=True, null=True, upload_to='images/')
listed_by = models.ForeignKey(User, on_delete=models.CASCADE, default="")
created_dt_tm = models.DateTimeField(auto_now_add=False, default=timezone.now())
class Bids(models.Model):
bidder = models.ForeignKey(User, on_delete=models.CASCADE, default="")
listing = models.ForeignKey(Listing, on_delete=models.CASCADE, default="", related_name="bids")
bid_price = models.IntegerField(default=0)
created_dt_tm = models.DateTimeField(auto_now_add=False, default=timezone.now())
Views:
def index(request):
return render(request, "auctions/index.html", {
"listings": Listing.objects.all()
})
HTML:
{% for listing in listings %}
<div style=display:flex;margin:30px;border:lightseagreen;border-style:solid;height:150px;border-width:1px;width:40%>
<div style=width:25%;display:flex;>
{% if listing.image %}
<img src="{{listing.image.url}}" alt="Cannot display image" height="100px" style="margin-left:50px;">
{% endif %}
</div>
<div style=width:15%></div>
<div style=width:30%>
<div>{{listing.title}}</div>
<div style=font-size:10pt;>Description: {{listing.description}}</div>
<div style=font-size:10pt;>Category: {{listing.category}}</div>
<div style=font-size:10pt;>Current Price: ${{ listing.bids_object.bid_price }}</div>
<div style=font-size:10pt;>Created by:<br>{{listing.listed_by}}</div>
</div>
<div style=width:30%>
<div style=margin:10px;>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
what you need is django's annotate functionality to find the max of each Listing.
from django.db.models import Max
def index(request):
return render(request, "auctions/index.html", {
"listings": Listing.objects.all().values().annotate(
max_bid_amount = Max('bids__bid_price')
)
})
in your html you can then add following line for max_bid.
<div style=font-size:10pt;>Max Bid Amount:<br>{{listing.max_bid_amount}}</div>

Django template loop through items with parent ID or PK

I'm trying to set up magnific popup on django.
My goal is to have one main picture in the homepage overview gallery view, which when clicked, would open a popup with the related images from the same photoshoot i.e. images with the same ID or PK.
I tried to apply the following approach
but i just cannot get it to work, maybe someone could help me out in this
My models.py
class Item(models.Model):
name = models.CharField(blank=False, max_length=200)
category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
order = models.IntegerField(blank=True, null=True)
active = models.BooleanField(blank=True, default=False)
objects = models.Manager()
class Meta:
verbose_name_plural = 'items'
def __str__(self):
return self.name
class ItemImage(models.Model):
image = ProcessedImageField(
blank=True,
null=True,
processors=[ResizeToFit(width=1680, upscale=False)],
format='JPEG',
options={'quality':90})
order = models.IntegerField(blank=True, null=True)
main = models.BooleanField(blank=True, default=False)
cover = models.BooleanField(blank=True, default=False)
item = models.ForeignKey(Item, related_name='items', blank=True, null=True, on_delete=models.SET_NULL)
objects = models.Manager()
class Meta:
verbose_name_plural = 'item images'
Views.py
def portraits(request):
port = ItemImage.objects.filter(item__category__slug='portraits', item__active=True, main=True,).order_by('item__order')
portall = ItemImage.objects.filter(item__category__slug='portraits', item__active=True).order_by('item__order')
context = {
'main_portraits': port,
'all_portraits': portall
}
return render(request, 'gallery/portraits.html', context)
and Template:
{% block content %}
<div class="grid">
{% for pic in main_portraits %}
<div class="item">
<div class="item">
<div class="outer-text">
<div class="text">
{{ pic.item.name }}
<p>Click to view gallery</p>
</div>
</div>
<a><img class="lazy" alt=""
sizes="(min-width:1400px) 1220px
(min-width:1000px) 1000px,
(min-width:500px) 700px,
(min-width:320px) 420px,
280px"
srcset="{{ pic.image_xs.url }} 280w,
{{ pic.image_s.url }} 420w,
{{ pic.image_m.url }} 700w,
{{ pic.image_l.url }} 1000w,
{{ pic.image_xl.url }} 1220w" />
</a> {{ pic.item.pk }}
</div>
<div class="lazy">
{% for p in all_portraits %}
{% endfor %}
</div>
</div>
{% endfor %}
</div>
{% endblock %}
I have set
z.item.pk
just as a test, to see if any of my manipulations result in the pk's to bunch up. For example the first for-loop returns a picture with PK "24", I need for the second for-lop to return only images with the same PK; and so for every image. I think the answer might be connected with _set.all function, just like in the related question above, but I cant seem to get it to work in my case. Feels like I'm missing something here.
current output:
<div class="grid">
<div class="item">
<div class="item">
<div class="outer-text">
<div class="text">
Palagā tītā
<p>Click to view gallery</p>
</div>
</div>
<a><img class="lazy" alt=""
sizes="(min-width:1400px) 1220px
(min-width:1000px) 1000px,
(min-width:500px) 700px,
(min-width:320px) 420px,
280px"
srcset="/media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/958ba5dbee5efe28fd2f5054b8f819e1.jpg 280w,
/media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/02d12ca7f0633fee2fc762cf96f7889e.jpg 420w,
/media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/ba5fa6633e92a288e3b2f47a713d64c2.jpg 700w,
/media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/fe0d559fef5b02434c43f841005d4961.jpg 1000w,
/media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/96d0e52dff14d1bc4b60bbec674565db.jpg 1220w" />
</a> 24
</div>
<div class="lazy">
</div>
</div>
You need prefiltered querysets containing the related images for every main image before handing over to the template.
def portraits(request):
ports = ItemImage.objects.filter(item__category__slug='portraits', item__active=True, main=True,).order_by('item__order')
for p in ports:
# You may not need the item__category__slug filter
# if there are only images of the same category
# associated with an item.
# Also, if you want to exclude the main image
# from the set of related images, you need to add the filter
# main=False
p.related_images = ItemImage.objects.filter(item__category__slug='portraits', item__id=p.item.id)
context = {
'main_portraits': ports,
}
return render(request, 'gallery/portraits.html', context)
Then you can loop over main_portraits in the template, and get the related images for each main image in a nested loop:
{% for mainp in main_portraits %}
{% for im in mainp.related_images %}
{# do something with the related images #}
{% endfor %}
{% endfor %}
You can break down the models like this it will make the querying easier.
# models.py
class Item(mdoels.Model):
name = models.CharField(blank=False, max_length=200)
category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
...
display_image = models.ProcessedImageField(...)
class ItemImage(models.Model):
item = models.ForeignKey(Item, related_name='images', blank=True, null=True, on_delete=models.SET_NULL)
image = models.ProcessedImageField(...)
...
#views.py
def portraits(request):
items = Item.objects.filter(category__slug='portraits', active=True)
return render(request, 'gallery/portraits.html', context={items: items})
#template
{% for item in items %}
<h1> {{item.name}} </h1>
<img src={{item.display_image}} />
{% for item_image in item.images.all %}
<img src={{item_image.image}} />
{% endfor %}
{% endfor %}

Retrieve info from many-to-many relationship in django temaplate

I am creating a blog and have a many-to-many relationship between the posts and categories.
class Category(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField()
def __str__(self):
return self.title
class Post(models.Model):
title = models.CharField(max_length=255)
subtitle = models.CharField(max_length=255,null=True,blank=True)
published_date = models.DateTimeField(auto_now_add=True)
draft = models.BooleanField(default=True)
body = RichTextField(config_name='blog')
slug = models.SlugField()
categories = models.ManyToManyField(Category)
featured = models.BooleanField(default=False)
I am trying to retrieve the the list of categories associated to an individual post within the template so I can display those category titles at the bottom of the post.
Here is the template code which displays the posts properly but not the categories.
{% for post in blog_posts %}
<div class="post">
<div class="date">
{{post.published_date|date:"M"}}
<span class="day">{{post.published_date|date:"d"}}</span>
<span>{{post.published_date|date:"Y"}}</span>
</div>
<div class="entry">
<div class="page-header">
<h2 class="post-title">{{post.title}}</h2>
</div>
<blockquote>
<p><strong>{{post.subtitle}}</strong></p>
</blockquote>
<p>{{post.body|safe}}</p>
<div class="well well-small">
<i class="icon-th-list "></i> Categories:LIST CATEGORIES HERE
</div>
</div> <!--entry div-->
</div><!--post div-->
{% endfor %}
Does anyone have thoughts on how I could retrieve the categories for a specific post? I greatly appreciate the time and expertise.
You can access the categories with this
{% for category in post.categories.all %}
{{ category.title }}
{% endfor %}
I also recommend adding .prefetch_related('categories') to the queryset in your view to reduce the number of sql queries.