django foreign key complex query - django

I know this is dumb but...
I have two model classes
class Gallery(models.Model):
name = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published', auto_now_add=True)
def __unicode__(self):
return self.name
class Image(models.Model):
gallery = models.ForeignKey(Gallery)
image = models.ImageField(upload_to='gallery/%Y/%m/%d')
caption = models.TextField(blank=True)
up_date = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.caption
I want three types of query
Get all the "Gallery" with one "Image" from that gallery
Get all the image from a single gallery
third one I can handle get a specific image from a "Image"

For #1: There's only one Gallery for each Image. If you have an image object img then the gallery for it is
gallery = img.gallery
For #2: To get all the images for a gallery:
imgs = gallery.image_set.all()

I think I understand what you're looking for.
Query #1
You want all galleries, along with a single image for each gallery. Since Django automatically allows you to access related objects you can accomplish this by simply retrieving all the galleries in your db.
select_related() automatically "follows" foreign-key relationships when it executes the query, which means later use of foreign-key relationships won't require database queries.
#selects all galleries ordered from newest to oldest
galleries = Gallery.objects.order_by('-pub_date').select_related()
To get the first image from each gallery in your template, you would do this:
{% for gallery in galleries %}
{{ gallery.name }}
<img src="{{ gallery.image_set.all.0.image }}">
{% endfor %}
https://docs.djangoproject.com/en/dev/ref/models/querysets/
https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#for
Query #2
This actually works exactly the same as the previous query, but for only a single gallery.
gallery = Gallery.objects.get(id=gallery_id).select_related()
In your template:
{% for image in gallery.image_set.all %}
<img src="{{ image.image }}"><br>
{{ image.caption }}
{% endfor %}

For #2:
If g is a gallery, then use:
g.image_set.all()

Related

Query Multiple Tables in Django and geta consolidated result

I am building a Blog application in Django and currently stuck at Querying the Data. I am creating a Post and then uploading multiple images to that post.
This is my Blog Post Model.
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
title = models.CharField(max_length=255)
description = models.CharField(max_length=1000,null=True)
Tags = models.CharField(max_length = 255,null=True,blank=True)
Created_date = models.DateTimeField(auto_now_add=True)
Updated_date = models.DateTimeField(auto_now=True)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
And this is my Images Model
class Images(models.Model):
Post = models.ForeignKey(Post,on_delete=models.CASCADE)
image = models.ImageField(upload_to='media/')
Now using this implementation I have 2 tables in DB in which data is stored as expected.
In the first tables all the details related to Post are being stored and in the second Table ID, Post_Id, Image_URL is being stored. If I upload 3 images then three rows are being created.
Now I want to Query the data that is -> I want all the posts and I want all the Images according to the Posts.
I can get seprate queries for Post and Images but how can this be done in Django ORM?
How can I query The data?
You can use like this;
post = Post.objects.all().prefetch_related('images_set').get(pk=1)
images = post.images_set.all() # this will bring you all images related to
post
Assuming you have a view that populates a context variable named posts with a queryset like Post.objects.all() your template could look something like this simplified
{% for post in posts %}
{{ post.title }}
{{ post.category }}
{{ post.description }}
...
{% for image in post.images_set.all %}
{{ image.image.url }}
{% endfor %}
{% endfor %}
Every time you iterate over post.images_set.all you will execute another query, you should use prefetch_related so that you don't perform a query each time and the data is cached
posts = Post.objects.prefetch_related('images_set')

Django Filter Query by Foreign Key

I'm struggling getting the right query for my project. Here is an example or my model :
from django.db import models
class Pictures(models.Model):
name = models.CharField(max_length=100)
bild = models.FileField(upload_to='article_pictures/')
articel = models.ForeignKey('articles', on_delete=models.CASCADE)
def __str__(self):
return self.name
class Articles(models.Model):
name = models.CharField(max_length=100)
text = models.TextField(max_length=2000)
published = models.BooleanField(default=False)
def __str__(self):
return self.name
how do I get the published artikles from the artikles class including the pictures (if there is one, or more)?
Thank you for your help
I don't think there is any exact query for this, but you can use prefetch_related to pre-load data from database. For example:
articles = Artikles.objects.filter(published=True).prefetch_related('pictures_set')
for article in articles:
article.pictures_set.all() # will not hit database
All published articles:
Articles.objects.filter(published=True)
A single published Article(Example):
article = Articles.objects.filter(published=True).first()
# and it's pictures
for picture in article.pictures_set.all():
print(picture)
Note: models have singular names, so you should rename Articles to Article and Pictures to Picture.
The related Pictures of an article article can be obtained with:
my_article.picture_set.all()
this is a queryset that contains all the related pictures.
We can obtain the Articles that are publised, and then fetch the related Pictures in two extra queries with:
articles = Article.objects.filter(published=True).prefetch_related('picture_set')
So in a template you can then render it like:
{% for article in articles %}
{{ article.name }}
{% for picture in article.picture_set.all %}
{{ picture.name }}
{% endfor %}
{% endfor %}

How to use multiple model instances in views in django?

I have created a website where when a user upload an image, I detect objects on that image and show them. So here is my model:
class Document(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
imgfile = models.FileField(upload_to='documents/%Y/%m/%d',default='settings.MEDIA_ROOT/default/default.jpg')
catagory = models.CharField(max_length=100,default="unknow")
The docfile is the original image, imgfile is an image where I label object in an image, catagory is the category of the object.
My problem is that there might be multiple objects in an image, thus I might have multiple Document instances in my views, but I don't know exactly how many instances I need in advance because this depends on the detection results.
So how can I implement this? And if I can use a Document list in views, how can I show contents in this list in my html template? Thx.
You can change your models a little:
class BaseImage(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
class Document(models.Model):
base_image = models.ForeignKey(BaseImage)
imgfile = models.FileField(upload_to='documents/%Y/%m/%d',default='settings.MEDIA_ROOT/default/default.jpg')
catagory = models.CharField(max_length=100,default="unknow")
That way you can query all the objects extracted from your base image with:
my_image = BaseImage.objects.get(pk=some_id)
my_extracted_objects = my_image.document_set.all()
It is possible then in your view to send that queryset in your context and in template display each one:
{% for document_object in my_extracted_objects %}
<img src="{{ MEDIA_URL }}{{ document_object.imgfile.url }}">
{% endfor %}
If i am missing something or misunderstood the question, please let me know.
Just as #cdvv7788 said, I made some changes:
In my views, I use:
my_images = Document.objects.filter(base_image=newdoc.id)
Where newdoc is a BaseImage instance, i.e. image uploaded by the user.
While in my html templates, I have the code below to list all detection result:
{%for image in my_images%}
<img src="{{image.imgfile.url}}">
{%endfor%}

List of Articles form FeinCMS Content Typs

my mission is to get a list of articles. This article come form a simple FeinCMS ContentType.
class Article(models.Model):
image = models.ForeignKey(MediaFile, blank=True, null=True, help_text=_('Image'), related_name='+',)
content = models.TextField(blank=True, help_text=_('HTML Content'))
style = models.CharField(
_('template'),max_length=10, choices=(
('default', _('col-sm-7 Image left and col-sm-5 Content ')),
('fiftyfifty', _('50 Image left and 50 Content ')),
('around', _('small Image left and Content around')),
),
default='default')
class Meta:
abstract = True
verbose_name = u'Article'
verbose_name_plural = u'Articles'
def render(self, **kwargs):
return render_to_string('content/articles/%s.html' % self.style,{'content': self,})
I would like to use that in different subpages.
Now it would be great to get a list of all articels on the main page (my projects -> list of project1, project2, project3, ).
Something like: Article.objects.all()
Template:
{% for entry in article %}
{% if content.parent_id == entry.parent_id %} #only projects
<p>{{ entry.content|truncatechars:180 }}</p>
{% endif %}
{% endfor %}
but i get a error "type object 'Articels' has no attribute 'objects'...
Do you have a smart idea? It would be grade to use Feincms ContentType.
FeinCMS content types are abstract, that means there is no data and no database table associated with them. Therefore, there's no objects manager and no way to query.
When doing Page.create_content_type(), FeinCMS takes the content type and the corresponding Page class and creates a (non-abstract) model which contains the actual data. In order to access that new, concrete model, you need to use content_type_for. In other words, you're looking for:
from feincms.module.page.models import Page
PageArticle = Page.content_type_for(Article)
articles = PageArticle.objects.all()

How to access properties of another table in one-to-many relationship using django template language?

I would like to use properties from different tables connected with one-to-many relationship in hardcoded img src in the template.
Models.py:
class Offers(models.Model):
province = models.CharField()
district = models.CharField()
location = models.CharField()
class OffersPhotos(models.Model):
offers_id = models.ForeignKey('Offers')
order = models.IntegerField()
Views.py:
def index(request):
latest_offers = Offers.objects.order_by('-creation_date')[:5]
context_dict = {'latest_offers': latest_offers}
return render(request, 'something.html', context_dict)
Template:
{% for offer in latest_offers %}
<img src="http://something.com/{{offer.id}}/{{offer.offersphotos.id}}.jpg">
{% endfor %}
{{offer.id}} works perfectly but how can I access id of the photo that has order=1 in the same line?
I think is not a good idea to query all the offerphotos given an offer and getting the first one in a template.
Instead you can define a property in your Offers class, soy you can get the first photo.
It should be something like this:
Models.py
class Offers(models.Model):
province = models.CharField()
district = models.CharField()
location = models.CharField()
def first_offerphoto(self):
return self.offerphotos_set.first()
Template
{% for offer in latest_offers %}
<img src="http://something.com/{{offer.id}}/{{offer.first_offerphoto.id}}.jpg">
{% endfor %}
Although you can still using the logics in your template:
<img src="http://something.com/{{offer.id}}/{{offer.offerphotos_set.first.id}}.jpg">
But i rather doing all queries before displaying info into templates