I am attempting to build a portfolio website and the idea was having a 'Project' model that contains multiple instances of an image. I think I was able to achieve this by using the 'ManyToManyField' relationship.
class Image(models.Model):
image = models.ImageField(upload_to='media/')
class Project(models.Model):
title = models.CharField(max_length=32)
description = models.TextField(default='', null=False)
stack = models.TextField(default='', null=False)
image = models.ManyToManyField(Image, related_name='images')
def __str__(self):
return self.title
From messing around a bit with the querying API, I've been able to retrieve the querysets for the images, but I am unsure how to keep those associated with their project and feed them into the context of my view. I already pass in an all() query for my Projects model (which is great), but I want to access the images as well.
Basically, I want my HTML template to end up looking like this:
{% for project in projects %}
<div class="card mx-auto" style="width: 50rem;">
<img class="card-img-top" src="{{ project.images }}" alt=""> // Issue here
<div class="card-body">
<p>{{ project }}</p>
<h5 class="card-title">{{project.title}}</h5>
<p class="card-text">{{project.description}}</p>
<p class="card-text">{{project.stack}}</p>
</div>
</div>
{% endfor %}
And here is the view:
def portfolio_view(request, *args, **kwargs):
p = Project.objects.all()
for project in p:
print('title: ', project.title)
print('description: ', project.description)
print('stack: ', project.stack)
print('images: ', project.image.all())
context = {
'projects': Project.objects.all(),
}
return render(request, 'main/portfolio.html', context)
Anything above the context object is just from testing.
Any help would be appreciated! Thanks a bunch!
Since you used a ManyToMany field, this means each project can have many images (and conversely each image can have many projects).
In this case you'll need to do something like this in your template:
{% for project in projects %}
...
{% for image in project.images.all %}
<img class="card-img-top" src="{{ image.image.url }}" alt="">
{% endfor %}
...
{% endfor %}
Let's assume we want only one image per project (and conversely only one project per image) i.e. a OneToOne field.
Your template would look like:
{% for project in projects %}
...
<img class="card-img-top" src="{{ project.image.image.url }}" alt="">
...
{% endfor %}
Related
I am trying to get the "About us" information from my database to my web application but its not displaying, what could be wrong...
here is the code from the database
class About(models.Model):
about_us = models.TextField()
achieve = models.TextField(blank=True)
image_abt = models.ImageField(upload_to="admin_pics", null=True)
class Meta:
verbose_name_plural = "About Us"
def __str__(self):
return self.about_us
and here is the Html code `
{% extends 'jtalks/base.html' %}
{% load static %}
{%block content%}
<section id="about-home">
<h2>About Us</h2>
</section>
<section id="about-container">
{% for about in abouts %}
<div class="about-img">
<img src="{{ about.image_abt.url }}" alt="">
</div>
<div class="about-text">
<h2>Welcome to TechEduca, Enhance your skills with best Online Courses</h2>
<p>{ about.about_us}</p>
<div class="about-fe">
<img src="images/fe1.png" alt="">
<div class="fe-text">
<h5>400+ Courses</h5>
<p>You can start and finish one of these popular courses in under our site</p>
</div>
</div>
<div class="about-fe">
<img src="images/fe2.png" alt="">
<div class="fe-text">
<h5>Lifetime Access</h5>
<p>You can start and finish one of these popular courses in under our site</p>
</div>
</div>
</div>
{% endfor %}
</section>
{% endblock %}
Nothing is displaying in the frontend of the website.
Thanks for sharing the view. You forgot to pass data to your template. To do that you have to create the queryset and pass that into a dictionary like below. Add the context variable to your render method so you can access the data in the template.
def about(request):
about = About.objects.all()
context = {
'abouts': about,
}
return render(request, 'jtalks/about.html', context)
also, in your html code i see { about.about_us}, but you have to use double curly brackets: {{ about.about_us }}
I am asking this question again because I did not receive a satisfactory answer in my previous attempt. It may be difficult for me to fully convey the issue I am trying to resolve, but I will do my best to provide a clear and concise explanation.
.
I am trying to run a query that retrieves a list of followers, as well as the list of followers and followings for each follower. I have included an image that illustrates this structure. I am currently using the following code to attempt this, but it is not producing the expected results. Can you help me understand what I am doing wrong and how I can correctly run this query?
views.py
def get_context_data(self, *args, **kwargs):
context = super(FollowerView,self).get_context_data(*args, **kwargs)
user = context['user']
user_com = User.objects.get(username=user)
myfollowers = user_com.is_following.all()
followers_Array =[]
followerings_Array =[]
for target_list in myfollowers:
user_obj = User.objects.get(username=target_list)
followers_obj = user_obj.is_following.all()
print(followers_obj,'name o ki line')
followerings_Array.append(followerings_Array)
print(followers_obj,user_obj)
followerings_obj = user_obj.userprofile.follower.all()
followerings_Array.append(followerings_obj)
print(followerings_obj,user_obj)
print(followerings_Array,'arry one one one ')
context['myfollowers_data']= followers_Array
context['myfollowerings_data']= followerings_Array
return context
I am currently using two arrays in my code, but I would prefer to avoid doing so if possible. My current implementation is not producing the desired output when I return the arrays in the context. Can you suggest an alternative approach that allows me to display the data in the manner illustrated in the image, and can you review the followers template to see if I am making any mistakes there?
{% for follower in user.is_following.all %}
<div class="followers-body">
<img class="img-responsive img-circle" src="{{follower.avatar.url}}" alt="">
<div class="name-box">
<h4>{{follower}}</h4>
<span>#{{follower}}</span>
<div class="followers-base">
<ul class="list-group">
<li class="list-group-item full-width">
<div class="pull-left" style="margin-right: 20px;">
{% if myfollowers_data %}
{% for user in myfollowers_data %}
<img src="{{user.userprofile.avatar.url}}" alt="" class="img-circle max-w-40 ">
{% endfor %}
{% endif %}
<span> {{myfollowers_data.count}} Followers </span>
</div><!--/ pull-left -->
</li>
<li class="list-group-item full-width">
<div class="pull-left">
{% for usr in myfollowerings_data %}
<img src="{{usr.userprofile.avatar.url}}" alt="" class="img-circle max-w-40 ">
{% endfor %}
<span> {{myfollowerings_data|length}} Following </span>
</div><!--/ pull-right -->
</li><!--/ list-group-item -->
</ul>
</div><!--/ followers-base -->
</div><!--/ name-box -->
<span> Follow</span>
</div><!--/ followers-body -->
{% endfor %}
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
follower = models.ManyToManyField(User, related_name ='is_following',blank=True,)
close_friends = models.ManyToManyField(User,related_name='my_close_friends', blank=True)
rank = models.ManyToManyField(Rank, related_name='rank', default='Newbie', blank=True)
avatar = models.ImageField(("Avatar"), upload_to='displays', default = '1.jpg',height_field=None, width_field=None, max_length=None,blank = True)
create_date = models.DateField(auto_now_add=True,null=True)
#property
def email_address(self):
return self.user.email
objects = ProfileManager()
def __str__(self):
return f'{self.user.username}'
def get_absolute_url(self):
return reverse("profiles:final_detail", kwargs={"username": self.user.username})
If more code in require than tell me in a comment session. I will update my question with that information.
Okay, this should all be achievable from the template:
template.html:
<!-- users followers -->
{% for follower1 in user.is_following.all %}
<img src="{{ follower1.avatar.url }}"/>
<!-- followers followers -->
{% for follower2 in follower1.is_following.all %}
<img src="{{ follower2.avatar.url }}"/>
...
{% endfor %}
{% endfor %}
I'm working on a portfolio project and I want to add multiple images on the Django admin site then displaying one of the header_image and title of a project on the home/list page (like card class functionality in bootstrap) and other images on the detail page. Is it possible?
Models.py
class MultiImage(models.Model):
header_image = models.ImageField(upload_to='media/')
title = models.CharField(max_length=100)
other_images = models.ImageField(upload_to='media/') # want this to be multiple image field
description = models.TextField()
link = models.URLField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
publish = models.BooleanField(default=True)
class Meta:
ordering = ('created', 'updated')
def __str__(self):
return self.title
index.html
{% for project in projects %}
<div class="col-lg-4 col-md-6 portfolio-item filter-app">
<div class="portfolio-wrap">
<img src="{{ project.image.url }}" class="img-fluid" alt="">
<div class="portfolio-links">
<i class="bx bx-plus"></i>
<i class="bx bx-link"></i>
</div>
</div>
</div>
{% endfor %}
detail.html
<div class="container">
<div class="portfolio-details-container">
<div class="owl-carousel portfolio-details-carousel">
<img src="{% static 'img/portfolio-details-1.jpg' %}" class="img-fluid" alt="">
<!-- all the images goes here -->
</div>
<div class="portfolio-info">
<h3>Project Information</h3>
<ul>
<li><strong>Project </strong>: {{ project.title }}</li>
<li><strong>Project Link to GitHub:</strong>: <a href="{{ project.link }}">{{ project.title }}</a </li>
</ul>
</div>
</div>
</div>
list/index page img
detail page img1
detail page img2
If you want to have several images stored against a single MultiImage object, the best way to do this is to create a separate image model (where you will store all of the images) and then point them back to the MultiImage instance with a foreign key. It will look something like this:
class Image(models.Model):
# add in anything else you want here
image = models.ImageField((upload_to='media/')
multiImage = models.ForeignKey(Reporter, on_delete=models.CASCADE, related_name='other_images')
This will mean, each image you create 'points' to a MultiImage instance. The related_name property is how you get all of the images you need. For example:
multi_image_instance = MultiImage.objects.get(id=...)
images = multi_image_instance.other_images # this will return a QuerySet
In the detail view you can do something like:
{% for image in images %}
<img src={image.image.url} />
{% endfor %}
I would like to get the Restaurant Id from the Restaurant model and use it for the href in the Lunchmenu listview. DonĀ“t really know how to move forward from here. I have tried a for loop of the "restaurants_list" in the template but did not really understand how to get only one Id from the list.
Is there any way to do this in the template?
Should I change the View somehow?
Models:
class LunchMenu(models.Model):
restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
class Restaurant(models.Model):
manager = models.ForeignKey(User, on_delete=models.CASCADE)
restaurant_name = models.CharField(max_length=100)
Listview:
class LunchMenuListView(ListView):
template_name = "lunchmenus/lunchmenu_home.html"
model = LunchMenu
def get_context_data(self, **kwargs):
context = super(LunchMenuListView, self).get_context_data(**kwargs)
context["restaurants_list"] = Restaurant.objects.all()
return context
Template:
<div class="row">
{% for lunchmenu in lunchmenu_list %}
<div class="col-lg-4 col-sm-6 portfolio-item">
<div class="card h-100">
<img class="card-img-top" src="http://placehold.it/350x200" alt="">
<div class="card-body">
<h4 class="card-title">
{{lunchmenu.restaurant}}
</h4>
<p class="card-text">{{lunchmenu.description | safe}}</p>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
Why not simply use restaurant field of the lunchmenu item like this:
<a href="/restaurants/{{ lunchmenu.restaurant.id }}">
Note that using hardcoded urls in this manner is not a best practice approach, you should use Django's built-in url template tag and use a named route which will give you a more robust solution with respect to the eventual changes in your urls scheme:
<a href="{% url 'restaurants:restaurant-detail' id=lunchmenu.restaurant.id %}">
(assuming that you have a restaurants:restaurant-detail route defined in your urls.py which takes restaurant.id as a parameter)
I am trying to filter an image through a category. It works but not the way I want it to. Here are how my models are setup:
class Image(models.Model):
CATEGORY_CHOICES = (
('Cover', 'Cover'),
('Scan', 'Scan'),
('Other', 'Other'),
)
title = models.CharField(max_length=256)
image = models.ImageField(upload_to="images/")
category = models.CharField(max_length=10, choices=CATEGORY_CHOICES)
contributor = models.ManyToManyField(Contributor, blank=True, null=True)
date_added = models.DateField(auto_now_add=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['title']
class Issue(models.Model):
...
images = models.ManyToManyField(Image, related_name="images_inc", blank=True, null=True)
....
def __unicode__(self):
return u'%s #%s' % (self.title, self.number)
def get_absolute_url(self):
return "/issues/%s" % self.slug
class Meta:
ordering = ['-date_added']
Views.py:
def issue(request, issue_slug):
issue = get_object_or_404(Issue, slug=issue_slug)
cover = Image.objects.filter(category='Cover')
scan = Image.objects.filter(category='Scan')
return render_to_response('comics/issue_detail.html', {'issue': issue, 'cover': cover, 'scan': scan}, context_instance=RequestContext(request))
I am trying to filter it by Cover or Scan, as you can see, but when I put this into my template:
{{ cover }} or {{ scan }}
It returns:
<Image: Astonishing X-Men 1 Cover A>] [<Image: Astonishing X-Men 1, teamshot>]
I need it to return the image URL, obviously. Adding {{ cover.url }} doesn't work.
Oh, and I just realized it does not display the specific image that is in the issue. It displays ALL images that categorized as either Scan or Cover.
In your current code, you're returning all the images, even the ones that aren't associated with your chosen comic issue. I'm assuming you want the ones for the selected issue. You probably want to do this instead:
def issue(request, issue_slug):
issue = get_object_or_404(Issue, slug=issue_slug)
try:
cover = issue.images_inc.filter(category='Cover')[0]
except IndexError:
cover = None
try:
scan = issue.images_inc.filter(category='Scan')[0]
except IndexError:
scan = None
return render_to_response('comics/issue_detail.html', {'issue': issue, 'cover': cover, 'scan': scan}, context_instance=RequestContext(request))
Then, in the template:
{% if cover.image %}
<img src="{{ cover.image.url }}" alt="{{ cover.image.title }}" />
{% endif %}
{% if scan.image %}
<img src="{{ scan.image.url }}" alt="{{ scan.image.title }}" />
{% endif %}
Update
If you do want more than one cover or scan, then you don't want to get only the first item. And really, you should probably just move this logic to models.py to avoid possible code duplication.
Something like this would be better:
# models.py
class Issue(models.Model):
...
def scans(self):
return self.images.filter(category='Scan')
def covers(self):
return self.images.filter(category='Cover')
# views.py
def issue(request, issue_slug):
issue = get_object_or_404(Issue, slug=issue_slug)
return render_to_response('comics/issue_detail.html', {'issue': issue }, context_instance=RequestContext(request))
Then, in the template:
<ul>
{% for cover in issue.covers %}
<li><img src="{{ cover.image.url }}" alt="{{ cover.image.title }}" /></li>
{% empty %}
<li>No cover</li>
{% endfor %}
</ul>
<ul>
{% for scan in issue.scans %}
<li><img src="{{ scan.image.url }}" alt="{{ scan.image.title }}" /></li>
{% empty %}
<li>No scans</li>
{% endfor %}
</ul>
filter always returns the list of matches in an array.
If you just want the first match, you could do something like this
cover = issue.images.filter(category='Cover')[:1][0]
scan = issue.images.filter(category='Scan')[:1][0]
But that will throw an exception if there is no match, so maybe better to wrap in in a try except such as
try:
cover = issue.images.filter(category='Cover')[:1][0]
except:
cover = None
In the template, since cover and scan represent image objects, you can get the url with this syntax:
{{ cover.image.url }} or {{ scan.image.url }}
The alternative if you want to see all of the images is to load covers and scans (plural) and check to see if they are non empty in your template. There is no need to except for the index error here, and it is much simpler.
In this case you would do:
covers = issue.images.filter((category='Cover'))
And then in the template:
{% if covers %}
{% for cover in covers %}
{{cover.image.url}} - {{cover.title}}
{% endfor %}
{% endif %}