How can I get the Author model objects into a queryset through the foreign key of B model? I would like to use the Author objects in my template.
#Models.py
class Book(models.Model):
name = models.CharField(max_length=5)
class Author(models.Model):
# lots of fields
class B(models.Model):
author = models.ForeignKey(Author)
book = models.ForeignKey(Book)
selected_book = "ABC"
book = Book.objects.get(name=selected_book)
original_queryset = B.objects.filter(name=book)
for i in original_queryset:
print(i.author) # returns what i want
queryset = # get all i.author objects somehow
return render(request,"template.html", {"queryset": queryset}
Remove the for loop. then add the following line after the original_queryset = B.objects.filter(name=book) line->
queryset = original_queryset.author
If this doesn't work then let me know. I hope I can help you.
You can rename your B model's author field to authors, that makes your code more meaningful because ForeignKey field can store many data. In your code, you have made your B model's author field as a ForeignKey field, which means books can have multiple authors. You can see the django documentation of ForeignKey reference.
If you change as I told you then don't forget to run migration(python manage.py makemigrations and python manage.py migrate command in your cmd) and change the line queryset = original_queryset.author to queryset = original_queryset.authors
Another approach
You can pass the original_queryset in the context of the template,(i.e: {'queryset':original_queryset }) then in your template.html, you can add tages like this:
{% for book in queryset %}
<ul>
{% for author in book.author %}
<li>author.name</li>
....
{% endfor %}
</ul>
{% endfor %}
By doing these, you can place your books and authors in your template nicely. If it still shows error, message me, I hope I can help you.
Related
I used PurchaseInfo.objects.filter(user=request.user).values() and want to show the result in templates. But, I get this error message:
FieldError at /auth/purchaseHistory/
Cannot resolve keyword 'user' into field. Choices are: id, product_name, product_price, purchase_addr, purchase_date, purchase_id, purchase_id_id, purchase_name, purchase_phone
purchaseinfo/models.py
class PurchaseInfo(models.Model):
purchase_id = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
purchase_name = models.CharField(max_length=30)
purchase_addr = models.CharField(max_length=100)
purchase_phone = models.CharField(max_length=15)
...and so on
customlogin/views.py
from purchaseinfo.models import PurchaseInfo
def purchaseHistory(request):
history = PurchaseInfo.objects.filter(user=request.user).values()
return render(request,'customlogin/purchaseHistory.html',{'history':history})
purchaseHistory.html
{% for i in history %}
<tr>
<td>{{i.purchase_id}}</td>
<td>{{i.purchase_name}}</td>
<td>{{i.purchase_addr}}</td>
<td>{{i.purchase_phone}}</td>
<td>{{i.product_name}}</td>
<td>{{i.product_price}}</td>
<td>{{i.purchase_date}}</td>
</tr>
{% endfor %}
How can I solve this problem?
Update your views to this:
history = PurchaseInfo.objects.filter(purchase_id=request.user).values()
In your model the foreign key relation to User model is purchase_id but in views you are trying to filter by user. You need to filter by purchase_id.
Most of time the error messages explain the problem pretty well, try to understand what it's saying and attempt to fix it on your own. Debugging is a nice skill to have.
I am very new to django. I have a django installation and am trying to create a UI in django for a few of the database tables.
In my database there are two tables - Articles and Author. The Articles table has a foreign key to Author table with field name as author_id.
I have managed to create a ListView class that lists articles. The code is like this:
from .models import Article
class ArticleListView(ListView):
template_name = "article.html"
context_object_name = 'articles'
paginate_by = 25
def get_queryset(self):
queryset = Article.objects.all().order_by('-created_at')
return queryset
Then in the view I loop the Article queryset and prints its fields, and this works fine. However I am not sure how to query the corresponding Author table in order to get the author name and details. Can anyone please help me understand how this can be done? I read a lot of documentation/tutorials about this but I am unable to wrap my head around how to do this. Any help is very much appreciated.
Please note: The Article model was written by earlier django programmer.
If you define a ForeignKey with name column to another model, then Django will construct a database column with the name column_id to obtain the primary key of the related object. But you can use .column to obtain the related object (so not the id, but the corresponding object of that id).
You can thus change the template, for example to:
<h1>Articles</h1>
<ul>
{% for article in object_list %}
<li>{{ article.pub_date|date }} - {{ article.headline }}
- {{article.author.name}}</li>
{% empty %}
<li>No articles yet.</li>
{% endfor %}
</ul>
(given of course an author has a name field).
Since you here will fetch all the author objects, it is usually more efficient to do a prefetch_related(..) on the queryset in that case:
class ArticleListView(ListView):
template_name = 'article.html'
paginate_by = 25
def get_queryset(self):
return Article.objects..prefetch_related(
'author'
).order_by('-created_at')
You can thus call .author on any Article instance to obtain the Author object that relates to it (and for instance fetch properties of that author, modify the author, etc.).
I have defined a relationship between two models of different app using foreign key and data is inserted into Db accurately with foreign key instance, but I want to fetch that data using Django ORM but I didn't get it, I have googled this issue and also checked stack-overflow questions but still my issues are not solved.
#models.py
class teamInfo(models.Model):
ownerID = models.IntegerField()
teamName = models.CharField(max_length=50)
def __unicode__(self):
return unicode(self.id)
class gameWorld(models.Model):
team = models.ForeignKey(teamInfo)
w = models.IntegerField(null=True)
l = models.IntegerField(null=True)
def __unicode__(self):
return unicode(self.id)
I have tried a few things in my views but nothing worked for me. Here is the latest thing I have tried in my views:
def teamStandings(request,template=None,context=None):
getAllTeamStat = gameWorld.objects.all()
for i in getAllTeamStat.teaminfo_set.select_related() :
raise Exception(i.teaminfo.teamName)
I simply want a Django ORM query which fetches data from both models so I can display the team name in templates
See here and try that:
class TeamStandingsView(ListView):
model = gameWorld
template = # Some template path here!
context_object_name = "games"
in template:
{% for game in games %}
{{ game.team.teamName }}
{% endfor %}
edit: this should work:
def teamStandings(request,template=None,context=None):
getAllTeamStat=gameWorld.objects.all()
for team in getAllTeamStat:
for teaminfo in team.teaminfo_set.all():
print teaminfo.teamName
I have models like these:
class Comment(models.Model):
text = models.TextField(max_length = 250, blank = False)
author = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
class Product(models.Model):
name = models.CharField(max_length = 40)
comments = generic.GenericRelation(Comment)
In this template I show the latest 5 comments of all products:
<ul>
{% for comment in last_comments %}
<li>{{ comment.author }} on {{ comment.content_object }}
<br>{{ comment.text }}</li>
{% endfor %}
</ul>
If I get last_comments with last_comments = Comment.objects.all().order_by('-id')[:5] django debug toolbar says was performed 25 queries.
If I get last_comments with last_comments = Comment.objects.select_related().all().order_by('-id')[:5] django debug toolbar says was performed 20 queries.
But why select_related doesn't select the related content_object also? In django debug toolbar I see 5 queries for getting the product. And are certainly the consequence of {{ comment.content_object }}
Probably the reason is because I use GenericForeignKey in Comment model.
Have you ideas about it?
You could try to refactor your database to look somewhat like this:
class Comment(models.Model):
...
content_object = models.ForeignKey(Content)
class Content(models.Model):
text = models.CharField(max_length=123)
class SomeSpecificContent(models.Model):
...
content = models.ForeignKey(Content)
class OtherSpecificContent(models.Model):
...
content = models.ForeignKey(Content)
which in case of Django would actually be a very similar schema to that of:
class Comment(models.Model):
...
content_object = models.ForeignKey(Content)
class Content(models.Model):
text = models.TextField()
class SomeSpecificContent(Content):
...
class OtherSpecificContent(Content):
...
as that is basically how the inheritence is handled in Django. The latter is probably less flexible and might be a little bit difficult to understand in case where SomeSpecificContent and OtherSpecificContent in fact represent totally different concepts.
Generic relations on the other hand cannot be handled efficiently exactly for this reason that they can link with whatever table you want them to. Therefore if you have a list of 5 objects it might happen, that each one of them is related to a different type of entity. Not sure how Django handles the case where 100 objects are related to 5 types of entities. Does it in fact generate 5+1 queries?
Good Morning All,
I've been a PHP programmer for quite some time, but I've felt the need to move more towards the Python direction and what's better than playing around with Django.
While in the process, I'm come to a stopping point where I know there is an easy solution, but I'm just missing it - How do I display manytomany relationships in a Django Template?
My Django Model: (most of the fields have been removed)
class Category(models.Model):
name = models.CharField(max_length=125)
slug = models.SlugField()
categories = models.ManyToManyField(Category, blank=True, null=True)
class Recipe(models.Model):
title = models.CharField('Title', max_length=250)
slug = models.SlugField()
class Photo(models.Model):
recipe = models.ForeignKey(Recipe)
image = models.ImageField(upload_to="images/recipes", blank=True)
So, there is the basic models I'm using in my application called "recipes."
With that said, there are two questions I'm looking for answers on:
How would I go about displaying the categories for a recipe on it's details page?
How would I go about displaying the image for the recipe on it's details page?
If I go into the Python shell, and input the following, I do get a result:
>>> photos = Photo.objects.filter(recipe=1)
>>> photos
[<Photo: Awesome Pasta>]
>>> for photo in photos:
... print "Photo: %s" % photo.logo
...
Photo: images/recipes/2550298482_46729d51af__.jpg
But when I try something like the following in my template, I get an error saying "Invalid block tag: 'photo.image'."
{% for photo in photos %}
{% photo.image %}
{% endfor %}
Although, even if that did work, the ID is still hard coded into the view, how would you go about having this dynamic for each recipe?
Details Page View.py snippet:
def details(request, slug='0'):
p = get_object_or_404(Recipe, slug=slug)
photos = Photo.objects.filter(recipe=1)
return render_to_response('recipes/recipes_detail.html', {'p': p, 'photos': photos})
Thanks in advance for the help and understanding for what is probably a very simple question to all of you!
UPDATE: When removing the additional fields in the models, I forgot the categories field for the Recipes model.
From what I can see, I think you've got a small syntax error:
{% photo.image %}
should instead be:
{{ photo.image }}
The {% %} notation is used for django template tags. Variables, on the other hand, are expressed with the {{ }} notation.
To make it dynamic, you can take advantage of the fact that your Photo model has a foreign key to Recipe. This means that there will be a reverse relation from the Recipe instance you've loaded using the slug back to the set of photos:
def details(request, slug='0'):
p = get_object_or_404(Recipe, slug=slug)
photos = p.photo_set.all()
Hopefully that will work for you. Glad to see you're enjoying working with Django!