Here is my Model.py
class BlogModel(models.Model):
blog_id = models.AutoField(primary_key=True)
title = models.CharField(max_length=1000)
content = FroalaField()
user = models.ForeignKey(User, blank=True , null=True , on_delete=models.CASCADE)
image = models.ImageField(upload_to='public')
created_at = models.DateTimeField(auto_now_add=True)
upload_to = models.DateTimeField(auto_now=True)
Here is my View.py
def my_blogs(request):
d = BlogModel.objects.all().filter(user = request.user)
return render(request,"my_blogs.html",{'message' : d})
But when I try to get the blog_id and created_at fields then it will shows an error that the requested fields are not present in the respective table.
But you can see that the field is n the table itself.
Please help
Here is the error i am getting
enter image description here
Django Queryset d is a list of objects. You have to loop through it:
for each_blog in d:
each_blog.blog_id
This is how you access the data for a filter method query set.
BlogModel.objects.all().filter(user = request.user) returns a query set i.e. a list of blogs satisfying the conditions.
You might want to iterate through all the blogs in order to display it, which can be done as follows:
{% for blog in d %}
{{ blog.blog_id }}
{% endfor %}
Try in views.py:
from .models import BlogModel
def my_blogs(request):
blogs = BlogModel.objects.all()
return render(request, 'my_blogs.html', locals())
In your html template my_blog.html try this:
{% for b in blogs %}
{{ b.id }}: {{ b.created_at }}
{% endfor %}
You can write in views.py:
def my_blogs(request):
# filtered queryset for login user
queryset = BlogModel.objects.filter(user=request.user)
return render(request,"my_blogs.html",{'blogs': queryset})
and in template my_blogs.html:
{% for blog in blogs %}
{{ blog.id }}
{{ blog.created_at }}
{% endfor %}
The BlogModel.objects.filter(user=request.user) returns a queryset which is list of your model objects. You can access object by iterating the queryset in template.
Related
This is my html file
{% for member in member_list %}
{% for batting in batting_list %}
{% if member.id == batting.member.id %}
{{ batting }}
<br>
{{ batting.match.id }}
<br>
{{ batting.runs }}
<br>
<hr>
{% endif %}
{% endfor %}
{% endfor %}
This is my models.py file
class Member(models.Model):
name = models.CharField(max_length=40, default='')
def __str__(self):
return str(self.name)
class Batting(models.Model):
member = models.ForeignKey(Member, on_delete=models.CASCADE, default='')
runs = models.IntegerField(blank=True, null=True)
match = models.ForeignKey(Match, on_delete=models.CASCADE, default='')
def __str__(self):
return str('{0} {1} scored {2} runs'.format(self.member, self.match.date, self.runs))
I am trying to figure out how I show the max runs for a member x in the html file. Currently I have been able to do it for the whole Batting table but not for the individual member! Any help please
You can query with:
from django.db.models import Max
member.batting_set.aggregate(
max_runs=Max('batting__runs')
)['max_runs']
This will be None if no related Battings exist.
You can annotate the Members queryset with:
from django.db.models import Max
member_list = Member.objects.annotate(
max_runs=Max('batting__runs')
)
and thus then render this with:
{% for member in member_list %}
{{ member.max_runs }}
{% endfor %}
You can use annotate over members to get their batting with highest runs value.
from django.db.models import Max
Member.objects.annotate(max_runs=Max("batting_set__runs"))
Then show {{ member.max_runs }} on your template.
You need to create annotation in your queryset which will contain highest runs for a member.
from django.db.models import Max
Member.objects.annotate(max_runs=Max('batting__runs'))
You can access it like a regular field
member_object.max_runs
I'm not sure about your view, but for a ListView the class will look like this
class MemberView(ListView):
template_name = 'tmp.html'
model = Member
def get_queryset(self):
return Member.objects.annotate(max_runs=Max('batting__runs')).all()
I'm new to Django. I'm trying to figure out how to get the tags property of MyModel (manytomany) onto the template (mytemplate.html) for each object in MyModel. Note: there are 4 possible tags in the Tags admin. Some of the objects from MyModel have 2 tags, some have 1. How do I get each object's unique selection of tags onto my template? Here are my files:
models.py
class Tag(models.Model):
CATEGORY_CHOICES = (
('dataset', 'dataset'),
('brand', 'brand'),
)
tag = models.CharField(max_length=100)
category = models.CharField(max_length=100, choices=CATEGORY_CHOICES)
class MyModel(models.Model):
id = models.CharField(max_length=30, primary_key=True)
publish_date = models.DateField()
tags = models.ManyToManyField(Tag)
views.py
from .models import MyModel, Tag
def index(request):
tags = Tag.objects.all()
infos = MyModel.objects.all().order_by('publish_date').reverse()
return render(request, 'mytemplate.html', {'infos': infos, 'tags':tags})
mytemplate.html
Right now this just creates 4 p elements- one for all 4 possible 'tags'
{% for info in infos %}
<small>{{info.publish_date}}</small>
{% for tag in tags %}
<p>{{tag.tag}}</p>
{% endfor %}
{% endfor %}
Try the following
{% for info in infos %}
<small>{{info.publish_date}}</small>
{% for tag in info.tags.all %}
<p>{{tag.tag}}</p>
{% endfor %}
{% endfor %}
I'm building a commenting system, which is working fine but i'm now trying to integrate voting. So I made another model to handle that and I tried to pair it using ForeignKey. Not too familiar with ForeignKey but i've looked at some other answers here to see how to render it in the template. I tried that using the nested for loop in my template below but {{ j.user }} doesn't render anything. Can anyone tell me what I'm doing wrong?
models.py
class Comment(models.Model):
destination = models.CharField(default='1', max_length=12, blank=True)
author = models.CharField(max_length=120, blank=True)
comment_id = models.IntegerField(default=1)
parent_id = models.IntegerField(default=0)
comment_text = models.TextField(max_length=350, blank=True)
timestamp = models.DateTimeField(default=timezone.now, blank=True)
def __str__(self):
return self.comment_text
class CommentScore(models.Model):
user = models.ForeignKey(User)
comment = models.ForeignKey(Comment)
upvotes = models.IntegerField(default=0)
downvotes = models.IntegerField(default=0)
views.py
...
comment_list = Comment.objects.filter(destination=id)
score = CommentScore.objects.all()
context = {
'score': score,
'comment_list': comment_list,
}
return render(request, 'article.html', context)
template
{% for i in comment_list %}
<div class='comment_div'>
<h3>{{ i.author }}</h3>
{% for j in comment_list.score_set.all %}
{{ j.user }} #nothing comes up
{% endfor %}
<p>{{ i.comment_text }}</p>
</div>
{% endfor %}
when using _set, the reverse relationship lookup, you must provide the full model name, you must also specify which instance this list of related models this "set" is for so it should be
{% for j in i.commentscore_set.all %}
{% empty %}
No scores found
{% endfor %}
You may also wish to set a related_name for the foreign key
comment = models.ForeignKey(Comment, related_name='scores')
...
{% for j in i.scores.all %}
I'm trying to understand the best way to display ForeignKey filtered data in a Django model.
I have three models reduced to this:
// models.py
class Publisher(models.Model)
def publisher_name = models.TextField()
def publisher_slug = models.SlugField()
def founded_year = models.IntegerField()
class Album(models.Model)
def album_name = models.TextField()
def publisher = models.ForeignKey('Publisher', related_name='albums')
class Song(models.Model)
def song_name = models.TextField()
def album = models.ForeignKey('Album', related_name='songs')
def published_year = models.IntegerField()
I have a URL that is composed of: /<publisher>/<published_year>/
The view I'm having trouble composing is supposed to be details like this:
Title of: Publisher.publisher_name
List of All Albums by the publisher: List of All songs from that album published the same year as the publisher__published_year: List of All songs from that album published as the url
The way, I've tried to do this that works right now is similar to this:
// views.py
class SongYearView(TemplateView):
def get_context_data(self, **kwargs):
context = super(SongYearView, self).get_context_data(**kwargs)
context['publisher'] = Publisher.objects.get(slug=kwargs['publisher_slug']
album_list=[]
for album in context['publisher'].albums.all():
single_album = dict()
single_album['album'] = album
single_album['publisher_year_song'] = album.songs.filter(published_year=context['publisher'].published_year)
single_album['filtered_year_song'] = album.songs.filter(published_year=kwargs['published_year']
album_list.append(single_album)
context['albums'] = album_list
return context
Then in the template I'm doing (with stripped out formatting)
// template.html
{{ publisher.name }}
{% for album in albums %}
{{ album.album.album_name }}
{% for song in album.publisher_year_song %}
{{ song.song_name }}
{% endfor %}
{% for song in album.filtered_year_song %}
{{ song.song_name }}
{% endfor %}
{% endfor %}
While this does work, it's not pretty and I'm pretty sure there are better ways of doing this.
This is an odd example, but just a basic example of my more detailed models. The way to think about it is Publisher -> Album -> Song or A -> B -> C. And I'm trying to get a view of all B items, that are only linked with a specific A item and then get two sets of C items for each B item, where one set is filtered on an A property and the other set is filtered on a passed argument from a URL.
I tried to get a custom model.Manager to help get this constructed, but didn't have much luck.
You could do add a custom template filter of_year:
#register.filter
def of_year(songs, year):
return songs.filter(published_year=year)
And change your template to
// template.html
{{ publisher.name }}
{% for album in publisher.albums %}
{{ album.album.album_name }}
{% for song in album.songs|of_year:publisher.founded_year %}
{{ song.song_name }}
{% endfor %}
{% for song in album.songs|of_year:filtered_year %}
{{ song.song_name }}
{% endfor %}
{% endfor %}
And clean your view:
// views.py
class SongYearView(TemplateView):
def get_context_data(self, **kwargs):
context = super(SongYearView, self).get_context_data(**kwargs)
context['publisher'] = Publisher.objects.get(slug=kwargs['publisher_slug'])
context['filtered_year'] = kwargs['published_year']
return context
Edit: rename the template filter
My view looks like this:
class PageView(DetailView):
queryset = Page.objects.all()
template_name = 'page.html'
def get_context_data(self, **kwargs):
context = super(PageView, self).get_context_data(**kwargs)
context['category'] = Category.objects.all()
context['categoryitem'] = CategoryItem.objects.all()
return context
When in template I try to execute the given context variables like so {{ category }} it prints out [<Category: Something not so interesting>] aka model name + it's title, I presume the title gets printed out because I've set __unicode__(self): return self.title in the model.py, but I cannot access any other fields from the given object. category.id is blank as so is everything else. How can I access those?
Your code is:
context['category'] = Category.objects.all()
So it should be:
context['categories'] = Category.objects.all()
And in your template:
{% for category in categories %}
{{ category.name }}
{% endfor %}
The output you got in your test makes sense:
[<Category: Something not so interesting>]
it's an array with only one entry, this entry is an object of the class Category, and the string representation of it is "Something not ..."
You need to iterate over the category, since it's queryset. E.g. in your template, you can do
<ul>
{% for c in category %}
<li> {{ c }} </li>
{% endfor %}
</ul>
category in template is queryset ( list of objects) not one single object. You need to iterate over it as
{%for c in category %}
{{c.id}} : {{ c.other_attribute }}
{%endfor%}