passing dynamic variable from parent template to child template in django - python

I have a template songs.html that includes a child template addToPlaylist.html. I need the title of the song that is to be added to the playlist dynamically.
Here is the code for songs.html which includes addToPlaylist.html.
{% for song in songs %}
<div class="col-16 col-sm-4 col-md-3 col-lg-2 single-album-item">
<div class="single-album">
<img src="{{MEDIA_URL}}{{song.image.url}}" alt="">
<div class="album-info">
<a href="{% url 'playSong' 'song' song.tittle %} ">
<h5>{{song.tittle}}</h5>
</a>
<p>{{song.album}}</p>
{% include "songs/addToPlaylist.html" with song_to_add=song.tittle %}
<a data-toggle="modal" href="#addToPlaylist" style="color: dimgrey; font-size: small;">Add to Playlist</a>
</div>
</div>
</div>
{% endfor %}
And this is the code for addToPlaylist.html
<div class="form-group" style="width: 100%;">
<ul class="list-group list-group-flush" style="width: 100%;">
{% for playlist in playlists %}
<li class="list-group-item">{{playlist.name}}</li>
{% endfor %}
</ul>
</div>
But assigning dynamic value to song_to_add does not work. The variable does not pass down to the child template.
This is the views.py code that passes the value of playlists
if request.user.is_authenticated:
playlists = Playlist.objects.filter()
songs = Song.objects.all()
return render(request, "songs\\songs.html", {'songs': songs, 'playlists':playlists,})
This is my Song model
class Song(models.Model):
GENRES = [
('Rock','Rock'),
('Hip Hop','Hip Hop'),
('Blues', 'blues'),
('Heavy Metal', 'Heavy Metal'),
('Classical', 'Classical'),
('Funk', 'Funk')]
tittle = models.CharField(max_length=255)
album = models.CharField(max_length=255, null = True, blank = True)
genre = models.CharField(max_length = 30, choices=GENRES)
image = models.ImageField(upload_to='images/', blank = True , null = True)
songFile = models.FileField(upload_to='musics/', help_text=("Allowed type - .mp3, .wav, .ogg"))
uploaded_at = models.DateTimeField(auto_now_add=True)
Also, I tried this solution.

What about your <h5>{{song.tittle}}</h5>? Is it displayed ok if you cut your bad code?
I think that your {{song.tittle}} returned empty string or None and it must be rewrite to {{song.title}}
If it's not answer for you, show your song model code please.

I solved my problem by putting child template modal form in the parent template file and assigning unique id to modal form. In this way I was able to call addToPlaylist for each song uniquely.

Related

restrict content on django views

I am trying to do this all vip user paid that contains type 2 allow to see the full information , but however it does as expect, but with a minor issue , it hide the lesson to the end-user if this doesnt belong to x user logged. I want to keep lesson displayed to the end-user, but however if the user tries to click to the lesson then display upgrade account instead of hidding content. how can I achieve this?
model
class Lesson(models.Model):
content_title = models.CharField(max_length=120)
content_text = models.CharField(max_length=200)
thumbnail = models.ImageField(upload_to='xxx/xxx/xxx/xxx/xxx')
link = models.CharField(max_length=200, null=True)
allowed_memberships = models.ManyToManyField(Membership)
def __str__(self):
return self.content_title
view
def get_context_data(self, **kwargs):
context = super(bootCamp, self).get_context_data(**kwargs)
lesson = Lesson.objects.first()
user_membership = UserMembership.objects.filter(user=self.request.user).first()
user_membership_type = user_membership.membership.membership_type
lesson_allowed_mem_types = lesson.allowed_memberships.all()
context['lessons_allowed_mem_types'] = lesson_allowed_mem_types
context['lessons'] = None
if lesson_allowed_mem_types.filter(membership_type=user_membership_type).exists():
if Lesson.objects.filter(allowed_memberships=1):
context['lessons'] = Lesson.objects.filter(allowed_memberships=1).values()
elif Lesson.objects.filter(allowed_memberships=2):
context['lessons'] = Lesson.objects.filter(allowed_memberships=2).values()
else:
pass
return context
template
{% if lessons is not None %}
{% for lessson in lessons %}
<div class="col-md-3">
<a href="/{{ lessson.link }}">
<div class="item">
<div class="content-overlay"></div>
<img src="/{{ lessson.thumbnail }}" />
<div class="content-details fadeIn-bottom">
<h3 class="content-title">{{ lessson.content_title }}</h3>
<p class="content-text">{{ lessson.content_text }}</p>
</div>
</div>
</a>
</div>
{% endfor %}
{% else %}
<p>upgrade</p>
{% endif %}
I would recommend to check the count of the retrieved lessons if it is less than 1 then redirect to the upgrade view/template.

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 do I nest the sub-categories right under the parent category during render

I want the sub-categories of each of my category objects rendered as a drop-down menu nested inside it's parent category.
I am having a hard time implementing that. How does it work?
This is my Category and SubCategory Models:
class Category(models.Model):
name = models.CharField(max_length=32)
class SubCategory(models.Model):
name = models.CharField(max_length=50)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
This is my view function:
def home(request):
categories = Category.objects.all()
#sub_categories = I don't know how
context = {
'categories': categories,
#'sub_categories': sub_categories
}
return render(request, 'blog/home.html', context)
This is inside my template:
{% for category in categories %}
<div class="nav-item dropdown">
<a href="#" class="py-3 nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ category.name }}
</a>
<div class="dropdown-menu rounded-0">
{% for sub_category in sub_categories %}
<a class="dropdown-item" href="#">
{{ sub_category.name }}
</a>
{% endfor %}
</div>
</div>
{% endfor %}
The categories are rendering fine, my problem is with the sub-categories.
Your sub_categories model needs to be somehow linked to the Categories Model.
You should have something like this inside your sub_categories model:
class Sub_categories(models.Model):
category = models.OneToOneField(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=200, null=True)
You can do this on your views.py:
def home(request):
categories = Category.objects.all().order_by('-date_posted')
context = {
'categories': categories,
}
return render(request, 'blog/home.html', context)
And in your template you can do this:
{% for category in categories %}
<div class="nav-item dropdown">
<a href="#" class="py-3 nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ category.name }}
</a>
<div class="dropdown-menu rounded-0">
{% for sub_category in category.sub_categories.all %}
<a class="dropdown-item" href="#">
{{ sub_category.name }}
</a>
{% endfor %}
</div>
</div>
{% endfor %}
I assume you could also use one ManyToManyField inside your Category model to make the category model related to the sub_category one.
This method does not require any changes to your models.
What I have had to do in cases like this is put categories and subcategories together in a single data structure and then just pass that entire thing to the template.
Here is some code for another project I have done. I was pairing a study with its list of participants.
views.py
participants = []
try:
studies = Study.objects.filter(investigators=Researcher.objects.get(user_id=request.user.id))
except (Study.DoesNotExist, Researcher.DoesNotExist) as e:
studies = []
participantList = []
for study in studies:
participantList = Approval.objects.filter(study=study)
if (len(participantList) == 0 ):
participants.append([[], study])
elif (len(participantList) == 1 ):
participants.append([participantList, study])
return render(request, 'manage.html',{'studies':participants, 'profile': user_profile})
template.html
{% for participants, study in studies %}
{{study.title}}
{% for part in participants %}
<p>{{part.info}}</p>
{% endfor %}
{% endfor %}
The key is essentially in pairing the required information together in a list and then iterating them together in the template to avoid the for loop problem.
As you are not pairing models with models, you can just replace the participantList = Approval.objects.filter(study=study) and all that with a call to a dict with the main category name as an argument.
In order to create subcategory models...
Category(models.Model):
name = models.Charfield()
Sub_Category(models.Model):
name = models.CharField()
category = models.ManyTOManyField(Sub_Category)
def home(request):
categories = Category.objects.all().order_by('-date_posted')
cid = #Generate your Category id single or list...
//you can ever it multiple time with for loop...
sub_categories = Sub_Category.objects.filter(category=cid)
context = {
'categories': categories,
'sub_categories': sub_categories
}
return render(request, 'blog/home.html', context)

Get related cousin model in a template

I'm struggling finding docs or examples how to get data from a cousin related model.
So if the models look like this:
class Part(models.Model):
name = models.CharField(max_length=550)
class Quantity(models.Model):
quantity = models.DecimalField(max_digits=10, decimal_places=2)
part = models.ForeignKey('Part', related_name='quantity_part')
stockarea = models.ForeignKey('StockArea', related_name='quantity_stockarea')
class Stock(models.Model):
name = models.CharField(max_length=550)
class StockArea(models.Model):
area = models.CharField(max_length=550)
stock = models.ManyToManyField(Stock, related_name='stockarea_stock')
def __str__(self):
return self.area
And in the view I get the part like this:
def details(request, part_id):
part = get_object_or_404(Part, pk=part_id)
context = {
'part': part,
}
return render(request, 'part/details.html', context)
Finally template trying to display the data:
{% for a in part.quantity_part.all %}
{{ a.quantity }} pcs
Find part in area: {{ a.stockarea }}
in stock: {{ part.stockarea.stock.name }}
{% endfor %}
You see how I try to get the name of the stock. I can't figure out how to be able to get hold of the name of the stock. I have a path there from the part.
Part have a related_name to the Quantity model called quantity_park. And in the model Quantity I have a relation to model StockArea. And from there I have a relation to model Stock.
Guidance is much appreciated =)
Maybe I'm totally doing this backwards. Maybe I'm defining the models wrong to begin with. I'm used to MySQL, so this is very new to me.
The data model for this is better done as:
from django.db import models
class Unit(models.Model):
name = models.CharField(max_length=32)
description = models.TextField()
abbrev = models.CharField(max_length=7)
class Warehouse(models.Model):
name = models.CharField(max_length=100)
address = models.TextField()
class StockArea(models.Model):
warehouse = models.ForeignKey(Warehouse)
# Adjust type of these identifiers as necessary
aisle = models.PositiveIntegerField()
shelf = models.PositiveIntegerField()
class Part(models.Model):
name = models.CharField(max_length=550)
description = models.TextField()
class Stock(models.Model):
part = models.ForeignKey(Part, related_name='stock') # Adds a 'stock' attribute to 'Part'
quantity = models.PositiveIntegerField()
unit = models.ForeignKey(Unit)
location = models.ForeignKey(StockArea)
View code:
from django.views import generic
from .models import Part
class PartView(generic.DetailView):
# Pre-fetch related objects. This also illustrates the joins
queryset = Part.objects.prefetch_related(
'stock', 'stock__location', 'stock__location__warehouse'
)
template_name = 'yourapp/part/detail.html'
Template code yourapp/part/detail.html:
{% extends "base.html" %}
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-md-8 col-md-offset-2">
<h1 class="title">{{ part.name }}</h1>
<p>{{ part.description }}</p>
<h2>Stock information</h2>
<div class="container-fluid">
{% for stock in part.stock.all %}
<div class="row">
<div class="col-xs-3">
Aisle {{ stock.location.aisle }}, shelf {{ stock.location.shelf }}
</div>
<div class="col-xs-3 label">
Warehouse:
</div>
<div class="col-xs-6">
{{ stock.location.warehouse.name }}
<address>
{{ stock.location.warehouse.address }}
</address>
</div>
</div>
<div class="row">
<div class="col-xs-3 label">
Available:
</div>
<div class="col-xs-8 numeric">
{{ stock.quantity }}
</div>
<div class="col-xs-1 unit">
{{ stock.unit.abbrev }} <sup><i class="fa fa-icon" title="{{ stock.unit.name }}"></i></sup>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock content %}
Edit:
Fixed model relation for stock/part.
Adjusted data model conforming specs in comments
Added view code to illustrate join and point to prefetch_related.
Adjusted template to match changes

Django get the foreign key object value

I wrote a model and saved some data, but now I don't know how to query the object along with the foreign key model.
Here is my models.py:
class Movie(models.Model):
link = models.URLField()
title = models.CharField(max_length=255, null=True)
title_en = models.CharField(max_length=255, null=True)
class MovieImage(models.Model):
movieimage = models.ForeignKey(Movie,null=True,blank=True)
img_link = models.URLField(max_length=255, null=True)
view.py:
def index(request):
obj = Movie.objects.all()
contacts = get_paginator(request, obj, 10)
return render_to_response("movie/index.html",
{'title': title ,'obj':obj,'contacts':contacts},
context_instance=RequestContext(request))
And movie/index.html:
{% for o in obj %}
<div class="col-md-12 item">
<p><h3>{{ o.title }}</h3></p>
<div class="pic">
{{ o.img_link }} <!--I want to show the img_link but don't know how to do this -->
</div>
</div>
{% endfor %}
I know I can use o.title ,o.entitle to get the value. But I don't know how to get the value in foreign key model from there
First - Some naming conventions - obj is a terribly general name that doesn't mean anything. It's probably a good idea to use something like movies. Also, if the model is named MovieImage, why have a field called img_link? That's kinda repetitive, don't you think? This way would be better:
#models.py
class MovieImage(models.Model):
movie = models.ForeignKey(Movie,null=True,blank=True)
src = models.URLField(max_length=255, null=True)
Then you could do:
#views.py
def index(request):
movies = Movie.objects.all() # movies instead of obj
contacts = get_paginator(request, movies, 10)
return render(request, "movie/index.html",
{'title': title ,'movies':movies,'contacts':contacts})
finally, for the actual answer - the default name for the related objects are foo_set (in your case, movieimage_set) which you can iterate over like so:
# html
{% for movie in movies %}
<div class="col-md-12 item">
<p><h3>{{ movie.title }}</h3></p>
<div class="pic">
{% for image in movie.movieimage_set.all %}
<img src="{{ image.src }}"> <!-- I am assuming you actually want to show the image, not just the link -->
{% endfor %}
</div>
</div>
{% endfor %}
p.s.
You might've noticed, I replaced render_to_response in the views with render. Here's why
As I told you on comments, you can have more than a MovieImage for each Movie, soy you need to iterate over them.
{% for o in obj %}
<div class="col-md-12 item">
<p><h3>{{ o.title }}</h3></p>
<div class="pic">
{% for image in o.movieimage_set.all %}
{{image.img_link}}
{% empty %}
<p>This obj doesn't have any image</p>
{% endfor %}
</div>
</div>
{% endfor %}

Categories

Resources