restrict content on django views - python

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.

Related

Notification template only printing out items after the 3rd position

Notification template only printing out items after the 3rd position. When I inspect element to check if its showing up in the frontend, its there, but its just a blank html <p> tag. Other than this minor bug it works fine. Not sure how to proceed, any help is much appreciated.
Here are my models.py
class Notification(models.Model):
MESSAGE = 'message'
APPLICATION = 'application'
CHOICES = (
(MESSAGE, 'Message'),
(APPLICATION, 'Application')
)
to_user = models.ForeignKey(User, related_name='notifications', on_delete=models.CASCADE)
notification_type = models.CharField(max_length=20, choices=CHOICES)
is_read = models.BooleanField(default=False)
extra_id = models.IntegerField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(User, related_name='creatednotifications', on_delete=models.CASCADE)
class Meta:
ordering = ['-created_at']
notification views.py
#login_required
def notifications(request):
goto = request.GET.get('goto', '')
notification_id = request.GET.get('notification', 0)
extra_id = request.GET.get('extra_id', 0)
if goto != '':
notification = Notification.objects.get(pk=notification_id)
notification.is_read = True
notification.save()
if notification.notification_type == Notification.MESSAGE:
return redirect('room', pk=notification.extra_id)
elif notification.notification_type == Notification.APPLICATION:
return redirect('room', pk=notification.extra_id)
return render(request, 'notification/notifications.html')
notifications.html template
{% extends 'main.html' %}
{% block content %}
<div class="container">
<h1 class="title">Notifications</h1>
{% if not notifications %}
No notifications yet!
{% endif %}
{% for notification in notifications %}
<div class="notification">
<p>
{% if notification.notification_type == 'message' %}
<a href="{% url 'notifications' %}?goto=room&notification={{ notification.id }}&extra_id={{ notification.extra_id }}">
<strong>{{ notification.created_by.username }}</strong> sent you a message<br>
<small>{{ notification.created_at|timesince }} ago</small>
</a>
{% elif notification.notification_type == 'application' %}
<a href="{% url 'notifications' %}?goto=room&notification={{ notification.id }}&extra_id={{ notification.extra_id }}">
<strong>{{ notification.created_by.username }}</strong> created a room<br>
<small>{{ notification.created_at|timesince }} ago</small>
</a>
{% endif %}
</p>
</div>
{% endfor %}
</div>
{% endblock %}
The notifications that only print an empty <P> probably don't have a notification_type that equals 'message' or 'application'.

Using fields from a aggregated QuerySet in a django template

So I got a QuerySet result from an aggregate function to display in a low-spec eBay clone of mine. But my problem is displaying certain fields in the Django template as I want, for example, I want to display the highest bidder's username and bid. When I call the whole object itself like so {{winner}}, then it displays. But when I try to access its fields like so {{winner.user_id.username}}, I get no output although the QuerySet does execute.
When I try to get a field like so (winner.user_id.username):
When I only call winner:
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
CATEGORIES = [
('Appliances', 'Appliances'),
('Tech', 'Tech'),
('Gaming', 'Gaming'),
('Fashion', 'Fashion'),
('Sports and Fitness','Sports and Fitness'),
('Other','Other'),
("Hygiene and Medicine","Hygiene and Medicine"),
("Stationery","Stationery"),
('Decor', 'Decor'),
('Furniture','Furniture'),
('Cars and Mechanical Things','Cars and Mechanical Things'),
("Tools","Tools")
]
# Create models here
class User(AbstractUser):
pass
class Auction_Listing(models.Model):
user_id = models.IntegerField(default=1)
list_title = models.CharField(max_length=64)
desc = models.TextField(max_length=600)
img_url = models.URLField(max_length=200, null=True, blank=True)
start_bid = models.IntegerField()
category = models.CharField(choices=CATEGORIES, max_length=35, null=True, blank=True)
active = models.BooleanField(default=True)
def __str__(self):
return f"ID:{self.id}, {self.list_title}: {self.desc}, {self.start_bid} posted by user:{self.user_id} in Category:{self.category}, url:{self.img_url}"
class Bids(models.Model):
user_id = models.ForeignKey('User', on_delete=models.CASCADE)
auctions = models.ForeignKey('Auction_Listing', on_delete=models.CASCADE, default=1,related_name='bidauc')
bid = models.IntegerField()
def __str__(self):
return f"ID:{self.id}, Bid {self.bid} posted by user:{self.user_id} on auction {self.auctions}"
class Auction_Comments(models.Model):
user_id = models.ForeignKey('User', on_delete=models.CASCADE)
comment = models.TextField(max_length=324, default='N/A')
auctions = models.ForeignKey('Auction_Listing', on_delete=models.CASCADE, default=1,related_name='comauc')
def __str__(self):
return f"ID:{self.id}, Comment: {self.comment} posted by user:{self.user_id} on auction {self.auctions}"
class Watchlist(models.Model):
user_id = models.ForeignKey('User', on_delete=models.CASCADE)
auctions = models.ForeignKey('Auction_Listing', on_delete=models.CASCADE, default=1, related_name='watchauc')
def __str__(self):
return f"ID:{self.id}, user:{self.user_id} on auction {self.auctions}"
views.py
def render_listing(request, title):
if request.method == "POST":
form = BidForm(request.POST)
bid = int(request.POST['new_bid'])
listing = Auction_Listing.objects.get(list_title=title)
comments = Auction_Comments.objects.filter(auctions=listing)
if bid <= listing.start_bid:
error = True
else:
error = False
listing.start_bid = bid
listing.save()
new_bid = Bids(user_id=request.user, auctions=listing, bid=bid)
new_bid.save()
return render(request, 'auctions/listing.html', {
"listing": listing,
"form": form,
"comments": comments,
"error": error,
"comform": CommentForm()
})
else:
form = BidForm()
comform = CommentForm()
listing = Auction_Listing.objects.get(list_title=title)
comments = Auction_Comments.objects.filter(auctions=listing)
high_bid = Bids.objects.filter(auctions=listing).aggregate(maximum=Max("bid"))
winner = Bids.objects.filter(auctions=listing, bid=high_bid['maximum'])
print(winner)
return render(request, 'auctions/listing.html', {
"listing": listing,
"form": form,
"comments": comments,
"error": False,
"comform": comform,
"winner": winner
})
template's code:
{% extends "auctions/layout.html" %}
{% load static %}
{% block title %} Listing: {{listing.list_title}} {% endblock %}
{% block body %}
{% if listing.active %}
<h2>{{ listing.list_title }}</h2>
<div class='listing'>
{% if listing.img_url == "" or listing.img_url == None %}
<a href='#'><img src="{% static 'auctions/img404.png' %}" class='img-fluid'></a>
{% else %}
<a href='#'><img src="{{ listing.img_url }}" class="img-fluid" alt='image of {{ listing.list_title }}'></a>
{% endif %}
<p>
{{ listing.desc }}
</p>
<p>
Current Bid: ${{ listing.start_bid }}
</p>
<p>Category: {{ listing.category }}</p>
<p></p>
{% if user.is_authenticated %}
<div class="bid">
<a href='{% url "watch" listing.list_title %}' class='btn btn-primary'>Add to/Remove from Watchlist</a>
{% if listing.user_id == user.id %}
<a href='{% url "close" listing.list_title %}' class='btn btn-primary'>Close Auction</a>
{% endif %}
</div>
<div class="bid">
<h3>Bid:</h3>
<form method="POST" action='{% url "renlist" listing.list_title %}'>
{% csrf_token %}
{{form}}
<button type="submit" class='btn btn-primary'>Make New Bid</button>
{% if error %}
Please enter a bid higher than the current bid.
{% endif %}
</form>
</div>
{% else %}
<p><a href='{% url "register" %}' class='register'>Register</a> to bid on this item and gain access to other features</p>
{% endif %}
</div>
<div class="listing">
<h3>Comments:</h3>
{% if user.is_authenticated %}
<div id='comform'>
<h4>Post a Comment</h4>
<form method="POST" action="{% url 'commentadd' %}">
{% csrf_token %}
{{comform}}
<button type="submit" class="btn btn-primary">Post Comment</a>
</form>
</div>
{% endif %}
<p>
{% for comment in comments %}
<div class="comment">
<h4>{{comment.user_id.username}} posted:</h4>
<p>{{comment.comment}}</p>
</div>
{% empty %}
<h4>No comments as of yet</h4>
{% endfor %}
</p>
</div>
{% else %}
<h2>This auction has been closed</h2>
<div>
<a href='{% url "watch" listing.list_title %}' class='btn btn-primary'>Add to/Remove from Watchlist</a>
</div>
<p>{{winner.user_id.username}}</p>
{% endif %}
{% endblock %}
Thanks in advance for the help!
Kind Regards
PrimeBeat
This will give a QuerySet. You can see in your second image.
A QuerySet represents a collection of objects from your database.
winner = Bids.objects.filter(auctions=listing, bid=high_bid['maximum'])
You need to iterate over that QuerySet, get whatever data you want and show it in your template.
{% for win in winner %}
<p>{{ win.user_id.username }}</p>
{% endfor %}

passing dynamic variable from parent template to child template in django

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.

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