Pass data from two models into one single html page - Django - django

i'm facing problem with show data from two models into single html page
i have two models - first called Course and second called Lesson okay , so i want add course then add lesson in the course and show data in one html page
models.py :
class Course(models.Model):
title = models.CharField(max_length=100,default="")
name = models.CharField(max_length=100,default="")
app_contect = RichTextField(blank=True,null=True)
app_image = models.ImageField(upload_to='images/',null=True, blank=True)
post_date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
post_tag = models.CharField(max_length=50,default="",choices = COURSE_SECTION)
objects = SearchManager()
slug = models.SlugField(default="",blank=True,unique=True,editable=True)
def save(self, *args, **kwargs):
if not self.id or not self.slug:
super(Course, self).save(*args, **kwargs)
self.slug = slugify(f"{self.title} {str(self.id)}")
super(Course, self).save(*args, **kwargs)
def get_image(self):
if self.app_image and hasattr(self.app_image, 'url'):
return self.app_image.url
else:
return '/path/to/default/image'
def __str__(self):
return self.name
class Meta:
ordering = ('-post_date',)
class Lesson(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
youtube_url = models.URLField()
def __str__(self):
return self.name
admin.py :
from django.contrib import admin
from blog_app.models import Course,Lesson
class InlineLessons(admin.StackedInline):
model = Lesson
class CourseAdmin(admin.ModelAdmin):
inlines = [ InlineLessons ]
admin.site.register(Lesson)
admin.site.register(Course,CourseAdmin)
so how to show data from course and lesson model into one html page ?
i tried do this but it's don't work , it just show data from Course model
views.py :
def course_posts(request,slug):
lesson = Lesson.objects.all()
course_posts = get_object_or_404(Course, slug=slug)
context = {'course_posts':course_posts}
return render(request,'course/course_posts_page.html', { 'course_posts': course_posts,'lesson':lesson })
html page :
<h1 id="font_control_for_header_in_all_pages"> {{course_posts.name}} </h1>
<div id="accordion">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0 text-center">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
{{lesson.name}}
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<iframe width="100%" height="400px" src="{{lesson.youtube_url}}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
</div>
</div>
this don't work , it's show data from Course model not from lesson and course

It looks like you want to display all the lessons associated with a course, so you should modify your view to not made the lesson query.
def course_posts(request,slug):
course_posts = get_object_or_404(Course, slug=slug)
context = {'course_posts':course_posts}
return render(request,'course/course_posts_page.html', { 'course_posts': course_posts })
<h1 id="font_control_for_header_in_all_pages"> {{course_posts.name}} </h1>
<div id="accordion">
{% for lesson in course_posts.lesson_set.all %}
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0 text-center">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
{{lesson.name}}
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<iframe width="100%" height="400px" src="{{lesson.youtube_url}}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
</div>
{% endfor %}
</div>

Related

Adding search bar function into a django project

I'm trying to add search bar in my application but I don't know how to query a database to gives the things that user's search for. I want when user search for a user in a post or category in a post of model to shows the result that user search for, like YouTube search and facebook search, How can i do this in django to give me what i want ?
this is my model:
class Photo(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.CharField(max_length=30,null=True, blank=False)
image = CloudinaryField(blank=False, null=False)
description = models.TextField(null=True)
date_added = models.DateTimeField(auto_now_add=True)
phone = models.CharField(max_length=12, null=False, blank=False)
price = models.CharField(max_length=30,blank=False)
location = models.CharField(max_length=20, blank=False)
def __str__(self):
return str(self.category)
my search form in dashboard template:
<div class="container">
<div class="row justify-content-center">
<form action="{% url 'search' %}" method="get">
<input class="form-control me-2" type="search" placeholder="Search" aria-
label="Search">
<br>
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
the post card in dashboard template:
<div class="container">
<div class="row justify-content-center">
{% for photo in photos reversed %}
<div class="col-md-4">
<div class="card my-2">
<img class="image-thumbail" src="{{photo.image.url}}" alt="Card image cap">
<div class="card-body">
<h2 style="color: yellowgreen; font-family: Arial, Helvetica, sans-serif;">
{{photo.user.username.upper}}
</h2>
<br>
<h3>{{photo.category}}</h3>
<h4>{{photo.price}}</h4>
</div>
<a href="{% url 'Photo-view' photo.id %}" class="btn btn-warning
btn-sm m-1">Buy Now</a>
</div>
</div>
{% empty %}
<h3>No Files...</h3>
{% endfor %}
</div>
</div>
the dashboard view:
def dashboard(request):
photos = Photo.objects.all()
context = {'photos': photos}
return render(request, 'dashboard.html', {'photos': photos} )
the search bar view:
def search(request):
return render(request, 'search.html')
urls:
path('', views.dashboard, name='dashboard'),
path('search/', views.search, name='search')
You can make it using filter method inside your view. Something like:
def dashboard(request):
photos_filter = request.GET.get('filtered[]', False)
photos = Photo.objects.all()
if photos_filter:
photos_filter = eval(photos_filter)
if photos_filter['id'] == 'category':
payments = payments.filter(
category__icontains=payments_filter['value'])
if photos_filter['id'] == 'user':
payments = payments.filter(
user__id=payments_filter['value'])
context = {'photos': photos}
return render(request, 'dashboard.html', {'photos': photos} )
And so on, you can add any filter you like. And in your URL you just add
/?filtered[]=%7B%22id%22:%22category%22,%22value%22:%22Nature%22%7D
Your code will see this filter like a dict obj: {'id': 'category', 'value': 'Nature'}. So after it, you'll get all photos with the category nature

How to query foreign key in Django with if conditions and do something if a condition is met

I'm working a website where I want to display product that are of two categories which are premium and free package and I want to filter all the premium package and label it with a star or a premium text to indicate it a premium package and for the free I'll do nothing. I don't know if I should user foreign key for this or tuple.
models.py:
STATUS_CHOICE = (
('draft', 'Draft'),
('in_review', 'In Review'),
('published', 'Published')
)
class Package_Category(models.Model):
title = models.CharField(max_length=10000, verbose_name="Title")
slug = models.SlugField(max_length=1000, unique=True)
def get_absolute_url(self):
return reverse("package-categories", args=[self.slug])
def __str__(self):
return self.title
class Meta:
verbose_name = "Package Category"
verbose_name_plural = "Package Categories"
class Vectors(models.Model):
title = models.CharField(max_length=10000, null=True, blank=True, verbose_name="Title")
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to="vectors-images/%Y/%m/%d/", default="default.jpg", verbose_name="Image Cover")
vec_file = models.FileField(upload_to='vector-uploads/%Y/%m/%d/', null=True, blank=True, verbose_name="Upload File")
category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name="Category")
package_category = models.ForeignKey(Package_Category, on_delete=models.CASCADE, verbose_name="Package Category")
tags = models.ForeignKey(Tag, on_delete=models.CASCADE, verbose_name="Tag")
status = models.CharField(choices=STATUS_CHOICE, default="published", max_length=150, verbose_name='Status')
creator = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="Creator")
creator_image = models.ImageField(upload_to="creators-images/%Y/%m/%d/", default="default.jpg", verbose_name="Creator Image")
created = models.DateTimeField(verbose_name="Created")
class Meta:
verbose_name = "Vector"
verbose_name_plural = "Vectors"
def get_absolute_url(self):
return reverse("vector-details", args=[self.slug])
def __str__(self):
return self.title
index.html:
{% for vector in vectors %}
<!-- Single Pricing Box -->
<div class="col-lg-4 col-md-6 col-sm-12">
<div class="_45lio">
<div class="_jk58o item_image_urip">
<img src="{{vector.image.url}}" class="img-fluid" alt="">
<i class="fa fa-download"></i>
<div class="image_urip_caption">
<div class="urip_caption_flex">
<div class="urip_author">
<div class="urip_avater">
<a href="author-detail.html.html" class="author-img">
<img src="assets/img/author.png" class="img-fluid" alt="" />
</a>
</div>
<div class="urip_avater_place">
<h3 class="urip_title">Adam vilson</h3>
<span>Liverpool, London</span>
</div>
</div>
</div>
<div class="urip_caption_last">
<div class="item_list_links">
<i class="fa fa-plus-circle"></i>
<i class="fa fa-heart"></i>
</div>
</div>
</div>
<div class="_io980 item_image_urip">
{% if package_category.premium %}
<h1>Premium Package</h1>
{% else %}
<h1>Free Package</h1>
{% endif %}
<h4 class="_95lp">{{vector.package_category}}</h4>
<span class="_ip76n">{{vector.category}}</span>
</div>
</div>
</div>
</div>
{% endfor %}
views.py:
from django.shortcuts import render
from . models import Vectors, Tag, Category, Package_Category
def index(request):
vectors = Vectors.objects.filter(status='published').order_by('-created')
context = {
'vectors': vectors,
}
return render(request, 'index.html', context)
you should do something like this if you are not using drf just by using the same model.
def index(request):
vectors = Vectors.objects.filter(status='published', package_category__title =="premimum").order_by('-created')
if vectors.exists():
// do something:
context = {
'vectors': vectors,
}
return render(request, 'index.html', context)
Although the best option would be to use serializers with drf

How to display multiple images in a django template img element

I am having a challenge displaying multiple images users post to one img template element, for one reason if i try fetching images with the default related name it wouldn't show in the template and i wonder what i am doing wrong. Can anyone be of help!
Here is my model for post.
class Post(models.Model):
page = models.ForeignKey(Page, on_delete=models.CASCADE, related_name="page")
username = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE ,related_name="page_user")
description = models.TextField(max_length=500, blank=True)
video = models.FileField(upload_to="PageVideos", blank=True)
pic = models.ImageField(blank=True)
date_posted = models.DateTimeField(auto_now_add=True)
tags = models.CharField(max_length=100, blank=True)
class Mete:
ordering = ['-date_posted']
def __str__(self):
return self.description
class PostImage(models.Model):
#page = models.ForeignKey(Page, on_delete=models.CASCADE, related_name="pg")
post = models.ForeignKey(Post, default=None, on_delete=models.CASCADE)
images= models.ImageField(upload_to="postimages/")
Here is my Detail view
def page_detail(request,id):
post = get_object_or_404(Post, id=id)
photos = PostImage.objects.filter(post=post)
context = {
'post':post,
'photos':photos
}
return render(request, 'page/detail.html',context)
These my Template to display users images
<div class="p-3 border-b dark:border-gray-700">
{{ post.description }}
</div>
<div uk-lightbox>
<div class="grid grid-cols-2 gap-2 p-2">
{% for p in photos.images_set.all %}
<a id="images" href="{{ p.images.url }}" class="col-span-2" >
<img src="{{ p.images.url }}" alt="" class="rounded-md w-full lg:h-76 object-cover">
</a>
<a href="">
<img src="" alt="" class="rounded-md w-full h-full">
</a>
<a href="" class="relative">
<img src="" alt="" class="rounded-md w-full h-full">
<div class="absolute bg-gray-900 bg-opacity-30 flex justify-center items-center text-white rounded-md inset-0 text-2xl"> + see more </div>
</a>
{% endfor %}
</div>
</div>
your photos is a list you dont need reverse m2m (the "images_set") simply change this in html
....
<div class="grid grid-cols-2 gap-2 p-2">
{% for p in photos %}
....
for optimize you can do this
from django.http import Http404
...
def page_detail(request,id):
try:
# with prefetch you do only one sql request
post = Post.objects.select_related('images_set').get(id=id)
expect Post.DoesNotExist as err:
raise Http404(err)
context = {
'post': post,
'photos': post.images_set.all()
}
return render(request, 'page/detail.html',context)

How to use sql data in django without any templete tag such as for is i only have a single data

I am building a portfolio and i am just learning django i tried to bring data from About in sql and since i have only single piece of data i dont need for loop so i tried putting it directly but is seems i cannot do that. Any suggestion on how i can do it
<section id="about">
<div class="container">
<div class="about-large d-none d-lg-block text-uppercase">About</div>
<div class="about-me row mt-5">
<div class="my-image col-md-5">
<img src="{{ about.image }}" />
</div>
<div class="my-description col-md-6">
<h3>About Me</h3>
<h4>I am {{about.name}}</h4>
<p>{{ about.description }}</p>
<p>{{ about.description_two }}</p>
<div class="cv-hire d-flex flex-start">
<button type="button" class="btn btn-dark font-weight-bold">
Download <i class="fas fa-download pl-2"></i>
</button>
</div>
</div>
</div>
</div>
</section>
My Views .py
from django.shortcuts import render
from django.views.generic import TemplateView
from .models import *
class HomeTemplateView(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['about'] = About.objects.first()
context['services'] = Service.objects.all()
context['works'] = RecentWork.objects.all()
return context
My models.py
from django.db import models
class About(models.Model):
image = models.ImageField(upload_to="static/img")
name = models.CharField(max_length=100,verbose_name="My Name")
description = models.CharField(max_length=500, verbose_name="Description")
description_two = models.CharField(max_length=500, verbose_name="Description", blank=True)
cv = models.FileField(upload_to="static/document")
class Meta:
verbose_name = "About Me"
verbose_name_plural = "About Me"
def __str__(self):
return "About Me"
I'd make some checks:
What returns About.objects.first() in Django shell?
Make template with {{ about.cv }} only to avoid other influences.
Then I can see if expected data exist and what incomes to template.

Django model form not showing data in bootstrap modal

So, I am new to the django and what I am trying to achive is to edit a comment in bootstrap modal.
My problem is that when I launch modal for editing specific comment, comment text isn't shown in modal. I am using the same CommentForm class for creating and editing comment, as I am using the same principle for the rest model classes in my app.
Here is the edit comment view:
def edit_comment(request, p_id):
comment = get_object_or_404(Comment, pk=p_id)
task_id = comment.task.id
task = get_object_or_404(Task, pk=task_id)
if request.method == "POST":
form = CommentForm(request.POST, instance=comment)
if form.is_valid():
form.save()
return redirect(reverse('task_details', kwargs={'p_id' : task.id}))
else:
data = {
'form' : CommentForm(instance=comment),
}
return render(request, "polls/task_details.html",data)
Because the list of all comments attached to the task are shown in task details, an this is where i launch edit modal, here is the view:
def task_details(request, p_id):
projects = Project.objects.filter(users=request.user)
task = get_object_or_404(Task, pk=p_id)
comments = Comment.objects.filter(task__id=p_id)
proj_id = task.project.id
project = get_object_or_404(Project, pk=proj_id)
if request.method == "POST":
data = {'task': task,
'comments': comments,
'project' : project,
'form' : CommentForm(),
'projects' : projects}
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.user = request.user
comment.type = "comment"
comment.task = task
comment.save()
return render(request, "polls/task_details.html", data)
else:
data = {'task': task,
'comments': comments,
'project' : project,
'form' : CommentForm(),
'projects' : projects}
data.update(csrf(request))
return render(request, "polls/task_details.html", data)
forms.py:
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ('comment_text',)
exclude = ('user', 'time_occurred', 'type', 'task', 'milestone')
widgets = {'comment_text': forms.Textarea(attrs={'class':"form-control",
'required':"",
'rows':3,
})}
labels = {"comment_text": _("Comment"),
}
urls.py:
url(r'^edit_comment/(?P<p_id>\d+)/$', views.edit_comment, {}, 'edit_comment'),
Comment is attached to the Task, and Comment inherits LogEvent abstract class, so here is the models.py part:
class Task(models.Model):
project = models.ForeignKey(Project)
user = models.ForeignKey(User, related_name='task_created_by')
assigned = models.ForeignKey(User, related_name='task_assigned_to', null=True)
priority = models.ForeignKey(Priority,null=True)
milestone = models.ForeignKey(Milestone)
name = models.CharField(max_length = 50)
description = models.CharField(max_length = 5000)
type = models.ForeignKey(Type, null=True)
state = models.CharField(max_length = 20, choices = State)
def __str__(self):
return self.name
class LogEvent(models.Model):
user = models.ForeignKey(User)
time_occurred = models.DateTimeField('time_occurred')
type = models.CharField(max_length = 50)
task = models.ForeignKey(Task, null=True, blank=True)
milestone = models.ForeignKey(Milestone, null=True, blank=True)
class Meta:
abstract = True
class Comment(LogEvent):
comment_text = models.TextField()
def save(self, *args, **kwargs):
''' On save, update timestamps '''
if not self.id:
self.time_occurred = datetime.datetime.today()
return super(Comment, self).save(*args, **kwargs)
def __str__(self):
return self.user.username
Finally, the template:
(This is the part of the task details template, where all comments attached to specific task are shown)
<div class="col-lg-12">
{% for comment in comments %}
<div class="well">
<p>
<i class="fa fa-fw fa-user"></i><strong>{{comment.user.get_full_name}}</strong>
<i class="fa fa-fw fa-clock-o"></i>{{comment.time_occurred}}
{% if comment.user == user %}
<a href=""
class="btn btn-info btn-xs btn-outline"
style="float: right; margin-left: 5px" data-toggle="modal" data-target="#EditModal{{forloop.counter}}"> <i class="fa fa-fw fa-edit"></i> Edit</a>
<!-- EDIT MODAL -->
<div class="modal fade" id="EditModal{{forloop.counter}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" >
<div class="modal-content" style=" border-color: #5cb85c;">
<div class="modal-header" style=" color: white;background-color: #5cb85c;border-color: #5cb85c;">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel" >Edit comment</h4>
</div>
<form action="{% url 'edit_comment' p_id=comment.id %}" method="post">
{% csrf_token %}
{% for field in form %}
<div class="modal-body">
{{field.errors}}
{{field}}
</div>
{% endfor %}
<div class="modal-footer">
<button type="button" class="btn btn-default btn-outline" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-success btn-outline" value="Save changes">
</div>
</form>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
{% endif %}
<p>{{comment.comment_text}}</p>
</div>
{% endfor %}
</div>
My question is what should I do to show the comment text in textarea inside the modal, or what have I missed, so the user can easily modify his comment, without copying the text before lauching the modal?