I am developing an application with Python Django and I'm new to it, in models.py I have
class SubTypeModel(models.Model):
importance = models.IntegerField()
name = models.CharField(max_length=70)
description = models.CharField(max_length=200)
class SubTypeModelImage(models.Model):
subType = models.ForeignKey(SubTypeModel)
image = models.ImageField(upload_to = "static/images/subtypemodels")
The admin.py is set properly and I can insert SubType with 3 different photos for each in database and photos are stored properly as well
The issue is started when I need to show them in template in the template.html file I have
{% for subType in all_subTypes %}
<li>
{{ subType.name }}
</li>
{% endfor %}
This can show the name of all the subType in database but I really have no idea how to show its photos as well
please help me how to add photos to view
in the views.py my query is like this :
list_models = SubTypeModel.objects.all();
Thanks in advance
{% for subType in all_subTypes %}
<li>
{{ subType.name }}
{% for image in subType.subtypemodelimage_set.all %}
<img src="{{ image.image.url }}" />
{% endfor %}
</li>
{% endfor %}
You can change subtypemodelimage_set to something nicer (like 'images') by setting the related_name argument on the foreign key field.
See https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.related_name
Related
I am developing an Instagram clone using Django. I wanted to show the latest two comments for each post.
As of now, I am only able to show all comments using the below code
home.html
{% for comment in post.comments.all %}
<p>{{ comment.user.username }}: {{ comment.description }}</p>
{% endfor %}
My models
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post_linked = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
description = models.CharField(max_length=500)
comment_posted_on = models.DateTimeField(default=timezone.now)
def __str__(self):
return "Comment by {} on {}".format(self.user.username, self.post_linked.caption)
Is there any way I cal display only the Latest two comment for each post?
You should create the collection of filtered comments in your view, then include that in the template's context. Django's template philosophy is to make them as simple as possible which generally means no function calls (except for template tags and filters).
To make things a bit more efficient you should utilize prefetch_related and Prefetch. Checkout the docs on them for the best reference.
from django.db.models import Prefetch
posts = Post.objects.all().prefetch_related(
Prefetch(
'comments',
Comment.objects.select_related('user').order_by('-comment_posted_on')[:2],
to_attr='latest_comments',
)
)
Then in your template:
{% for comment in post.latest_comments %}
<p>{{ comment.user.username }}: {{ comment.description }}</p>
{% endfor %}
The django templatetag "slice" will help you out here:
https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#slice
With your code:
{% for comment in post.comments.all|slice:":2" %}
<p>{{ comment.user.username }}: {{ comment.description }}</p>
{% endfor %}
This assumes your model for comments is ordered by most recent first. You might need to add that to class Meta for the Comment model.
I am preparing a image gallery for my website using Django . I have basically a Gallery Model Foreign Key in my Image Model. I have a BooleanField in my Image model to make a cover photo.
What I need is to get True value for the one in between images.
{% for gallery in gallery_list %}
<div class="grid-item {{ choices | random }}">
</div>
{% endfor %}
I checked the documents for custom filters trying to solve but I could not figure out. Can you help me ?
Thanks
Ps Edit: adding my models
class Gallery(models.Model):
title = models.CharField(max_length=200,verbose_name=_("gallery_title"),help_text _("Enter the Gallery title"))
class Image(models.Model):
title = models.CharField(max_length=200,verbose_name=_("image_title"),help_text _("Enter the Image title"))
gallery = models.ManyToManyField(Gallery)
is_cover_photo = models.BooleanField()
You could write a method in Gallery model to return you a cover image:
class Gallery(models.Model):
# other fields
def cover_image(self):
return self.image_set.filter(is_cover_photo=True).first()
Then in template:
{% for gallery in gallery_list %}
{% with cover=gallery.cover_image %}
{% if cover %}
{# do something with cover image #}
{% endif %}
{% endwith %}
{% endfor %}
It's good to keep complex logic like this outside of your templates to avoid them getting too complicated. Save it for the views and/or models!
Sounds like the best bet here would be to have a method on your Gallery model to get the Image that has the cover image. Something like:
class Gallery
...model fields...
def get_cover_image(self):
return self.images_set.filter(cover_photo=True).first()
Then in your template, assuming the Image model has a property like url:
{% for gallery in gallery_list %}
<div class="grid-item {{ choices | random }}">
</div>
{% endfor %}
To save lots of DB queries here you might need/want to use prefetch_related to get all the Image objects you'll need to display the galleries, but that's a different question.
Given the following code:
Models.py
class Advertisement(models.Model):
title = models.CharField(null=True, blank=True, max_length=30)
created_by = models.ForeignKey(User)
class Gallery(models.Model):
advertisement = models.ForeignKey(Advertisement, related_name='images')
image = models.ImageField(upload_to=image_directory_path, help_text="Your ad image (Recommended size: 1024x768)")
creation_date = models.DateTimeField(editable=False, default=timezone.now)
Views.py
def do_foo(request):
search_result = Advertisement.objects.all().order_by('-creation_date')
return render(request, 'content_search.html',
{
'search_result': search_result
})
page.html
{% for ad in search_result %}
{% for ad_image in ad.gallery_set %}
<img src="{{ ad_image.image.url }}">
{% endfor %}
{% endfor %}
How do I access the backwards relation between Advertisement and Gallery? I tried ad.gallery_set and ad.images_set but I could not get the images.
I tried to follow what they say here Django Relation Objects Reference and in this topic.
Your code has related_name="images". So ad.images it is.
Edit: as shredding notes correctly, you can't use that directly if you want to loop over it, and need to add .all to get a queryset object:
{% for ad_image in ad.images.all %}
<img src="{{ ad_image.image.url }}">
{% endfor %}
Maybe related name "galleries" would be a bit more clear.
I want to check that user_id exists in the profile_images table from my Django template.
My Model
class profiles(models.Model):
profile_id = models.AutoField(primary_key=True)
user = models.ForeignKey(User)
-----
class Profile_images(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User)
image = models.ImageField(upload_to='uploads/',default = 'uploads/no-img.jpg')
My View
def view_profiles(request):
if request.user.is_authenticated():
view_all_profiles = profiles.objects.all()
profile_image = Profile_images.objects.all()
return render_to_response('profiles/all.html', {'profiles':view_all_profiles,'profile_image':profile_image}, context_instance=RequestContext(request),)
else:
return HttpResponseRedirect('/accounts/login/')
My Template
{% for profile in profiles %}
<li>
{% for image in profile_image %}
{% ifequal image.user_id profile.user_id %}
<img src="{{MEDIA_URL}}{{image.image}}" alt="image" />
{% endifequal %}
<!-- i want to check here if not user_id exist in profile_images table -->
{% if profile.user_id not in profile_image %}
<img src="{% static 'images/no-image.jpg' %}" alt="image" />
{% endif %}
{% endfor %}
</li>
{% endfor %}
{% if profile.user_id not in profile_image %} is not working. I'm new to Django & python and I'm stuck here. Please suggest better ways if my code is not correct.
in your view you could get all user_ids with a profile image, something like:
user_ids_with_profile_images = Profile_images.objects.all().values_list('user_id', flat=True)
Then in your template you could check if profile.user_id not in user_ids_with_profile_images.
It might actually be a little cleaner to loop through all the users with profiles in your system and get their profile images through the foreign key, instead of looping through all the profiles and trying to get the users...
This is really a design problem, you've got a separate model specifically for a profile image when that could just be a field on the profile model itself.
class Profile(models.Model): # convention is to use a non-plural name for models
# No need to explicitly set the primary key, this will be added automatically
# profile_id = models.AutoField(primary_key=True)
user = models.ForeignKey(User)
image = models.ImageField(upload_to='uploads/',default = 'uploads/no-img.jpg')
-----
Now it would just be a case of using {{ profile.image }} with no need for any additional looking up.
I've got a model, and my instance called "show_user_image":
class user_image(models.Model):
title = models.CharField(max_length=50)
img = models.imageField(upload_to='/home/blabla')
def show_user_image(self):
return u'<img src="%s" />' % self.img.url
show_user_image.short_description = 'User image'
image_img.allow_tags = True
off course i can use it at my admin list:
list_display = ('title', 'show_user_image')
And my question is: how to use this instance in the edit form?
Something like here:
http://new-media.djangobook.com/content/en/1.0/chapter17/book_extra.png
{% extends "admin/change_form.html" %}
{% block form_top %}
<p>Insert meaningful help message here...</p>
{% endblock %}
but i want:
{% extends "admin/change_form.html" %}
{% block form_top %}
{{ MY-INSTANCE-HERE }}
{% endblock %}
I just need to image display above the form.
Thanks!
John.
The form is admin template is available via adminform.form variable. Your field is named img, so it will be like this (untested):
{% block form_top %}
<img src="{{ adminform.form.img.value }}"/>
{% endblock %}
BTW. Class names in python should use CapitalizedWordsNamingConvention, according to official style guide. You should name the model UserImage instead of user_image.
BTW2: show_user_image is a method, not an instance.