Related Objects Reference Django - python

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.

Related

How do I show navbar items based on a model field in Django?

I have a Blog model that looks like this:
class Blog(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blogs')
parent = models.CharField(max_length=50, choices=PARENT_TUTORIALS)
def get_absolute_url(self):
return reverse("blog_list", args=[str(self.parent), str(self.slug)])
I can succesfully display all the blogs on a table of contents via my table.html template:
{% for blog in blog_list %}
<li>{{blog.title}}</li>
{% endfor %}
However, I want to show only those blogs that have the same Blog.parent value as the current blog page. For example, the page example.com/biology/page1, has biology as a parent. When the user is on that page, the table of contents should show only the pages that have biology as a parent.
Why not just add an if statement like so?
template.html
{% for blog in blog_list %}
{% if blog.parent == current_blog.parent %}
<li>{{blog.title}}</li>
{% endif %}
{% endfor %}
Another option is to filter with js, something like (untested):
template.html
{% for blog in blog_list %}
<li class="blog-list-item {{blog.parent}}">
{{blog.title}}
</li>
{% endfor %}
script.js
$('.blog-list-item').filter(':not(.biology)').hide();

How do you get queryset objects related to queryset passed to templates in Django

I have these two models and as you can see they have a relationship.
class Post(models.Model):
text = models.TextField()
class PostImage(models.Model):
post = models.ForeignKey(Post, default=None, on_delete=models.CASCADE)
image = models.FileField(upload_to = 'media/',blank=True, null=True)
As far as I understand if I query posts and push them to a template and post, I would expect to use something like this in my templates to retrieve the images URL attached to the posts but it doesn't seem to work.
{% for post in posts %}
{% for post_image in post.post_image_set.all %}
{{post_image.image.url}}
{% endfor %}
{% endfor %}
What am I doing wrong?
Here is my views.py file.
views.py
# Create your views here.
def index(request):
posts=Post.objects.filter(approved=True).order_by('-published_date')
context = {"posts":posts}
return render(request, 'post/home.html',context)
The default related name for a foreign key relational is the name of the model (PostImage) but in your template for loop you called it post_image Following relationships “backward”
change
{% for post_image in post.post_image_set.all %}
into
{% for post_image in post.postimage_set.all %}
Template code (with change)
{% for post in posts %}
{% for post_image in post.postimage_set.all %}
{{post_image.image.url}}
{% endfor %}
{% endfor %}

Fetch Django models in list view to show both

I have this models:
Article:
class Article(models.Model):
sku = models.CharField(
max_length=5,
primary_key=True,
validators=[MinLengthValidator(5)]
)
ean = models.CharField(
max_length=13,
unique=True,
validators=[MinLengthValidator(13)]
)
parent = models.ForeignKey(
'Article',
related_name='children',
null=True,
blank=True,
on_delete=models.PROTECT
)
...
and ArticleTranslations:
class ArticleTranslation(models.Model):
LANGUAGE_CHOICES = (
(settings.ENGLISH, _("english")),
(settings.FRENCH, _("french")),
(settings.GERMAN, _("german")),
(settings.ITALIAN, _("italian")),
(settings.PORTUGUESE, _("portuguese")),
(settings.SPANISH, _("spanish")),
)
article = models.ForeignKey(
'Article',
on_delete=models.CASCADE,
related_name='translations',
)
I need to return both, combined to show the 2 items in a Django Templates HTML for. Need to have the item and the foreign key and see it in the same iterations. I wanna do it with the methods of the class List View and django, and not doing something bad.
I have this ListView:
def get_queryset(self):
queryset = (Article.objects
.all()
.prefetch_related('translations')
.order_by('-sku'))
print(queryset)
return queryset
And in my HTML, need to show the foreign key values:
{% extends "base.html" %}
{% block content %}
{% for article in article_list %}
<div class="container">
<h2>{{ article.translations.NEED_TO_SHOW_THAT_PARAMETER }}</h2>
</div>
{% endfor %}
{% endblock content %}
In your view you're already getting right data. So in your template you can simply loop through the Article objects and it's foreign key values (as they can be accessed using related_name)
you're using {% for article in article_list %} so I believe you have context_object_name = 'article_list' set in your views.
I'm guessing extra fields for translations model which you're probably wanting to access. If your model looks something like this:
class ArticleTranslation(models.Model):
LANGUAGE_CHOICES = (
(settings.ENGLISH, _("english")),
(settings.FRENCH, _("french")),
(settings.GERMAN, _("german")),
(settings.ITALIAN, _("italian")),
(settings.PORTUGUESE, _("portuguese")),
(settings.SPANISH, _("spanish")),
)
article = models.ForeignKey(
'Article',
on_delete=models.CASCADE,
related_name='translations',
)
language = models.CharField(max_length=10, choices=LANGUAGE_CHOICES)
Then in your template you can do:
{% extends "base.html" %}
{% block content %}
{% for article in article_list %}
<div class="container">
{% for object in article.translations.all %}
<h2>Chosend language - {{ object.language }}</h2>
{% endfor %}
</div>
{% endfor %}
{% endblock content %}
Explanation:
article.translations.all will give you all translations for one article, using this you can get the field value

Django: Check that row exists in list

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.

Django foreign key relation in template

i know you will say that this question is asked before many times but i havent solved it yet...
models.py
class Doc(UploadModel):
doc_no = models.CharField(max_length=100, verbose_name = "No", blank=True)
date_added = models.DateTimeField(verbose_name="Date", default=datetime.now,
editable=False)
class DocImage(models.Model):
property = models.ForeignKey(Doc, related_name='images')
image = FileBrowseField("Docs", max_length=200,
directory="doc_img/%Y/%m/%d/%H/%M/%S/",
extensions=[".jpg",".tif"], blank=True, null=True)
views.py
def doc_detail(request, dosc_no):
res = Doc.objects.filter(doc_no = dosc_no)
return render_to_response("doc/doc_detail.html", {"result": res})
templates:
{% for i in docimage.property_set.all %}
{{ i.image.url }}
{% endfor %}
i have tried above template but i didnt get any result. so i want to get imageurl adress in DocImage class...
all helps
If you review the foreign key documentation, if you have a relationship like
Doc -> has many DocImages
you need to define your foreign key on the DocImages class like so:
class DocImage(models.Model):
property = models.ForeignKey(Doc, related_name='images')
If you don't set related names, you can access the DocImages from the Doc like:
Doc.docimage_set.all()
Docs on Related Objects
But setting related_name in the property field lets you do
Doc.images.all()
Just make sure whatever you pass to the template in the view context matches what is used in the template, e.g.
# in the view
return render_to_response('mytemplate.html', { 'mydoc' : doc, 'mydocimage' : img }
This can then be used in the template as follows:
# and in your template to get the images attached to the document
{% for i in mydoc.images.all %}
...
{% endfor %}
# or to get the document the image belongs to
{{ mydocimage.property.date_added }}
first you iterate over the result
the images related to a Doc are retrieved by the images property of doc which is generated from the related_name attribute in the ForeignKey
code:
{% for doc in result %}
{% for docimage in doc.images.all %}
{{ docimage.image.url }}
{% endfor %}
{% endfor %}

Categories