How can I make different html formats for media files according to its extension in Django? - django-views

when looping through all the media files in template passed variable i am getting video and image same styles. From the looped items i need to give different style for images and different style for videos.
here is my template file (gallery.html)
{% for photo in photos %}
<div class="col-md-4">
<div class="card my-2">
<video class="video-thumbail" controls="controls" src="
{{photo.image.url}}" alt="Card image cap"></video>
<image class="image-thumbail" src="
{{photo.image.url}}" alt="Card image cap">
<a href="{% url 'keyhtml' %}"
class="btn btn-outline-dark btn-sm m-1">View</a>
</div>
</div>
{% empty %}
<h3>No photos...</h3>
{% endfor %}
here is my views function for this
#login_required(login_url='login')
def gallery(request):
user = request.user
category = request.GET.get('category')
if category == None:
photos = Photo.objects.filter(category__user=user)
else:
photos = Photo.objects.filter(
category__name=category,
category__user=user)
if category == None:
photos2 =
Photo2.objects.filter(category__user=user)
else:
photos2 = Photo2.objects.filter(
category__name=category, category__user=user)
categories = Category.objects.filter(user=user)
context = {'categories': categories, 'photos': photos,'photos2': photos2}
return render(request, 'photos/gallery.html', context)

Related

Django: Create a dynamic sidebar template and use it in other templates

NOTE: This question is not about creating or using a base template!
I'm creating a products app in my project, using only django and html/css, and all pages in this part has a sidebar nav menu that categorizes different product models and types. So this sidebar will be used in all other product pages.
Here is my views.py file:
from django.shortcuts import render
from .models import (
Product,
Usage,
SubUsage,
MainModel,
PumpType,
HeadFlowDataSet,
)
def products_usage_main(request):
product_queryset = Product.objects.all()
usage_queryset = Usage.objects.all()
sub_usage_queryset = SubUsage.objects.all()
main_model_queryset = MainModel.objects.all()
pump_type_queryset = PumpType.objects.all()
context = {
"product_queryset": product_queryset,
"usage_queryset": usage_queryset,
"sub_usage_queryset": sub_usage_queryset,
"main_model_queryset": main_model_queryset,
"pump_type_queryset": pump_type_queryset,
}
return render(request, "products/products_usage_main.html", context)
def sidebar_data(request):
usage_queryset = Usage.objects.all()
sub_usage_queryset = SubUsage.objects.all()
main_model_queryset = MainModel.objects.all()
pump_type_queryset = PumpType.objects.all()
context = {
"usage_queryset": usage_queryset,
"sub_usage_queryset": sub_usage_queryset,
"main_model_queryset": main_model_queryset,
"pump_type_queryset": pump_type_queryset,
}
return render(request, "products/products_sidebar.html", context)
And the sidebar template is as shown below:
<ul class="nav flex-column list-unstyled my-3 ms-3">
{% for usage_item in usage_queryset %}
<li class="nav-item p-2 ms-4">
<a href="#" class="text-decoration-none nm-text-color fw-semibold"
data-bs-toggle="collapse"
data-bs-target="#usage_{{ usage_item.usage_name_fa }}">
<i class="fa-solid fa-angle-left me-2 icon-selector"></i>
الکتروپمپ‌های {{ usage_item.usage_name_fa }}
</a>
<ul class="submenu collapse" id="usage_{{ usage_item.usage_name_fa }}"
data-bs-parent="#nav_accordion">
{% for sub_usage in sub_usage_queryset %}
{% if sub_usage.usage == usage_item %}
<li class="my-2 ms-4">
<a href="#" class="text-decoration-none nm-text-color fw-semibold">
{{ sub_usage }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
And now I'm creating a proucts main page for example, which should implement this sidebar.
I included this sidebar template in my products page template as shown below:
<section>
<div class="container-fluid">
<div class="row">
<div class="col-6 col-lg-4 px-0">
{% include "products/products_sidebar.html" %}
</div>
<div class="col-6 col-lg-8">
content
</div>
</div>
</div>
</section>
Now, I know that without a URL, the view sidebar_data() won't be called, and for now my urls are as shown below:
urlpatterns = [
path("application/", products_usage_main, name="products_usage_main"),
path("application/<str:pk>", product_detail, name="product_detail"),
]
And as expected, context data sent in the sidebar_data() view, will not be sent and so my sidebar will not be populated with the data.
How am I supposed to acheive this?
There is one way, in which I have to send the queryset data sent to sidebar in all the different product pages, but I think there should be a more sufficient way.
Your help is appreciated in advance.
To achieve this you need to pass the same context in your all views. A simple demonstration of your views would be as follows:
views.py
# Since these context will be common to all views it would be written outside any view function
def get_common_queryset():
usage_queryset = Usage.objects.all()
sub_usage_queryset = SubUsage.objects.all()
main_model_queryset = MainModel.objects.all()
pump_type_queryset = PumpType.objects.all()
queryset_dictionary = {
"usage_queryset": usage_queryset,
"sub_usage_queryset": sub_usage_queryset,
"main_model_queryset": main_model_queryset,
"pump_type_queryset": pump_type_queryset,
}
return queryset_dictionary
# and in every other views
def products_usage_main(request):
...
context_of_view = {
...
}
common_context = get_common_queryset()
context = {**context_of_view, **common_context} # dictionary expansion
return render(request, "template_name.html", context)

For loop inside a IF condition to show right category on django template

I'm trying to show the correct articles in the category section using an if condition with a for loop inside, so far I'm displaying all the articles and not the only ones that supposed to be in the category.
home.html screeenshot
home.html
{% if articles.category == Sports %}
{% for article in articles %}
<div class="position-relative">
<img class="img-fluid w-100" src="{{article.cover.url}}" style="object-fit: cover;">
<div class="overlay position-relative bg-light">
<div class="mb-2" style="font-size: 13px;">
{{article.title}}
<span class="px-1">/</span>
<span>{{article.created_at}}</span>
</div>
<a class="h4 m-0" href="">{{article.description}}</a>
</div>
</div>
{% endfor %}
{% endif %}
views.py
def home (request):
cats = Category.objects.all()
articles = Article.objects.filter( is_published=True).order_by('-category')
return render (request,'pages/home.html',
context={
'cats': cats,
'articles': articles
})
Instead of hardcoding it like that, you could let the users search for categories with something like this:
articles = Article.objects.filter(category__icontains=q).values('title')
where q would be the user input in the form.

i cant specify a user to access my post in django

its a bit tricky for i tried solving it but cant,i am using class based views with customuser model, i have a blog post with multiple user i want to make it in a way only the main authour of a post should be allowed to delete or update post but i dont seems to know what to do or how to set it,here is my code kindly take a glance and release me from debugging,instead i get what i want wont get nothing and inatead i get something every author has the right to delete each other's post plus this is how i want it to look like when the user view its blog_detail but for non user it should be blank [![enter image description here][1]][1]
views.py
class BlogUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Blog
fields = ['title', 'categories', 'overview', 'thumbnail', 'summary']
def form_valid(self, form):
form.instance.user = Doctor.objects.get(user=self.request.user)
return super().form_valid(form)
def test_func(self):
blog = Doctor.objects.get(user=self.request.user)
if self.request.user == blog.user:
return True
return False
class BlogDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Blog
success_url = reverse_lazy('blog')
def test_func(self):
blog = Doctor.objects.get(user=self.request.user)
if self.request.user == blog.user:
return True
return False
blog_detail.html
{% extends "pages/base.html" %}
{% load static %}
{% block title %}Jazeera Blog{% endblock title %}
{% block meta %} the best medical-service website in Abuja {% endblock meta %}
{% block content %}
<br><p></p>
<section class="ftco-section bg-light" id="blog-section">
<div class="container">
<div class="row justify-content-center mb-5 pb-5">
<div class="col-md-10 heading-section text-center ftco-animate">
<h2 class="mb-4">Gets Every Single Updates Here</h2>
<p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia</p>
</div>
</div>
<div class="container">
<div class="row justify-content-center mb-5 pb-5">
<div class="col-lg-8 ftco-animate">
<h2 class="text-center">{{ object.title }}</h2>
<div class="meta mb-3 text-center">
<div><h6><span><a href = "">written By {{ object.user }}</span><small class="date"><i class="icon-clock"></i> {{ object.timestamp|timesince }} ago</small><a/></h6>
</div>
</div>
<div><small class="icon-eye text-danger">{{ object.view_count }}</small></div>
<div class="meta mb-3 text-center">
<h5>{% for cat in object.categories.all %}<span class="btn btn-dark">{{ cat }}</span> {% endfor %}</h5>
</div>
<p class="text-center">{{ object.overview }}</p>
{% if object.created_by == user %}
<a class="btn btn-secondary btn-sm mt mb-2" href="{% url 'blog-update' blog.id %}">Update</a>
<a class="btn btn-danger btn-sm mt mb-2" href="{% url 'blog-delete' blog.id %}">Delete</a>
{% endif %}
</div>
</div>
</div>
</div>
</section>
{% endblock content %}
##urls.py
path('blog/', BlogListView.as_view(), name='blog'),
path('blog/<int:pk>/', BlogDetailView.as_view(), name='blog-detail'),
path('blog/<int:pk>/update/', BlogUpdateView.as_view(), name='blog-update'),
path('blog/new/', BlogCreateView.as_view(), name='blog-create'),
path('blog/<int:pk>/delete/', BlogDeleteView.as_view(), name='blog-delete'),
[1]: https://i.stack.imgur.com/aojDX.jpg
You can restrict the set of Blog objects in the queryset to the ones that are written by the request.user:
class BlogDeleteView(LoginRequiredMixin, DeleteView):
model = Blog
success_url = reverse_lazy('blog')
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
user=self.request.user
)
This will return a HTTP 404 error, if a user aims to remove a Blog object post where the post.user is not the logged in user.
In your views (BlogUpdateView and BlogDeleteView), update test_func to become;
def test_func(self):
blog = Doctor.objects.get(pk=self.kwargs.pk)
return self.request.user == blog.user
If you're testing for one condition in multiple views as you just did, it will be better creating a separate class for the test. Say, IsOwnerMixin where you perform the test and then inherit it in the required view(s).
Additionally, you can change {% if object.user == user %} in your blog_detail.html to become {% if user.is_authenticated and object.user == request.user %}
Good luck!

django-jinja href not downloading file

Hey guys I was making a page where people can download my stuff.I made a model of thta and It is succesfull in uploading that but the problem i swhen I click on the download button front end I t doesn,t download that stuff .Instead of that it downloads the copy of the page.
Here,s the models.py
class Upload(models.Model):
image = models.ImageField(upload_to = 'images',)
file = models.FileField(upload_to = 'images/%Y/%M/%d/')
name = models.CharField(max_length = 200)
def __str__(self):
return self.name
Here,s the views.py
def upload(request):
upload = Upload()
return render(request,'app/download.html',{'upload':upload})
Here,s the html file
{% block content %}
<div class="container">
<div class="download">
<p style="text-align: center;">
<img src="{{upload.image}}" alt="Image containing link to you,r success">
</p>
</div>
<h2>Click on the button below</h2>
<button class="btn btn-primary"><a href="{{upload.file.id}}" download>Yeah do it</a></button>
</div>
{% endblock %}
try
{% block content %}
<div class="container">
<div class="download">
<p style="text-align: center;">
<img src="{{upload.image}}" alt="Image containing link to you,r success">
</p>
</div>
<h2>Click on the button below</h2>
Yeah do it
</div>
{% endblock %}
Changes explained:
{{upload.file.url}} will give you the url to your uploaded file.
directly add "btn btn-primary" to your anchor tag. It'll display as button. You don't need seperate <button> tag

Django templates {% block content %} can contain only two form fields?

The question is: Can we send in the form into the template with more than 2 fields(I'm sure it should be possible). Please, advice what might be the issue:
I've created the form with 3 fields:
class Email(forms.Form):
owner = forms.ChoiceField(choices=['Tyler', 'Aleks'])
title = forms.CharField(max_length=150, label='Name the stuff')
file = forms.FilePathField(path=path, label='Enter the path')
Afterward, operated it in view, where I'm sending form object to the template:
def mail_distribution(request):
if request.method == 'POST':
form = Email(request.POST)
if form.is_valid():
render(request, 'general/email.html', {'form': form})
else:
form = Email()
return render(request, 'general/email.html', {'form': form})
Here is the template itself:
{% extends 'general/base.html' %}
{% block content %}
<form class="form-vertical" action="mail_distrib" role="form" method="post">
{% csrf_token %}
<div class="form-group" style="display: inherit">
<center>
{{form.title}}
</center>
</div>
<div class="form-group" style="display: inherit">
<center>
{{form.owner}}
</center>
</div>
<div class="form-group" style="display: inherit">
<center>
{{form.file}}
</center>
</div>
<center><input type="submit" value="OK"></center>
</form>
{% endblock %}
Afterwards I get the error:
*Error during template rendering
In template E:\Tyler\Projects\Web_dev\dj_api\Scripts\distribution\general\templates\general\email.html, error at line 13
too many values to unpack (expected 2)
line13 - 13 {{form.owner}}*
Change choices attribute in owner fields like this
owner = forms.ChoiceField(choices=[('Tyler','Tyler'), ('Aleks', 'Aleks')])