I am trying to pass a list of objects from my views.py to my html template but I can't access the objects model attributes at my HTML template. Please, check the code below:
class.py:
class FOF(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=200)
size = models.IntegerField()
pub_date = models.DateTimeField('date published')
view_count = models.IntegerField()
def __unicode__(self):
return self.name
class Frame(models.Model):
url = models.CharField(max_length=200)
fof = models.ForeignKey('FOF', related_name='frame_set')
index = models.IntegerField()
def __unicode__(self):
return self.url
views.py:
def my_fof(request, fof_name_value):
my_list = FOF.objects.all().order_by('-rank')
...
return render_to_response('uploader/my_fof.html', {'my_list':my_list}, context_instance=RequestContext(request))
I usually can access the attributes at the html file when I pass a single object but once I am passing a list of objects, it seems impossible to access those attributes.
For example, when I type alert({{ fof_list.0 }}); it prints the object attribute name, because it was defined in the models.py:
def __unicode__(self):
return self.name
But once I try to access any of its attributes, as pub_date: alert({{ fof_list.0.pub_date }}); it returns undefined, as that attribute is unavailable or unreachable.
Any Idea on how to proceed to reach those attributes when passing an entire list? Or how to proper pass that list?
Cheers.
Use the for template tag to iterate over an iterable and get each element in turn.
You first need to place the content of attribute in a javascript variable.
<script>
var pub_date = '{{my_list.0.pub_date}}';
alert(pub_date);
//this will also work
alert('{{my_list.0.pub_date}}') # enclosed in single or double quotes
</script>
Use a for loop and iterate it to get each object in a template.
{% for obj in my_list %}
<span>{{obj.pub_date}}</span>
<span>{{obj.size}}</span>
---
{% endfor %}
Related
I want to create object in my comment model.
It's my Reply model to a post.
class Reply(MPTTModel):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
detail = models.CharField(max_length=50, null=True, blank=True, unique=True)
pub_date = models.DateTimeField(auto_now_add=True)
last_edited = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
class MPTTMeta:
order_insertion_by = ['name']
It's my view function for reply.
def post_detail(request,id,**kwargs):
post = Post.objects.all().filter(id=id)
comment = CommentReply.objects.filter(post=id)
context = {'post': post, 'comment': comment}
if request.method == 'POST':
comments = request.POST.get('comment')
Reply.objects.create(
post=post, detail=comments, author = request.user)
else:
return render(request, 'khalidblog_app/full_detail.html', context)
return render(request,'khalidblog_app/full_detail.html',context)
I'm using for loop in my template:
{% for post in post %}
<img alt='' src='{{ post.image.url }}' class='avatar avatar-80 photo' height='80' width='80' />
<div class="eltd-author-description-text-holder">
<h5 class="eltd-author-name"> {{post.author}} </h5>
<div class="eltd-author-text">
<p>{{post.title}}</p>
</div>
<div class="eltd-author-text">
<p>{{post.content}}</p>
<hr>
</div>
{%endfor%}
When I run this view function It shows a value error as follows.
Cannot assign "<QuerySet [<Post: Author : zorainTiTleFirst PostDated :2021-01-17 16:27:47.043869+00:00>]>": "Reply.post" must be a "Post" instance.
How I can set the forignkey(Post) in this reply model using this view function?
On the very first line of your function, you are using .filter() method which returns QuerySet (List of Objects in short), where you should have ideally used .get() method.
.get() returns a single object which the assignment on line 6 actually expects.
Your 'post' variable is pointing to a QuerySet of Post objects, rather than a single instance. You should use get() instead of filter() as follows:
post = Post.objects.get(id=id)
Update: You shared in the comments that you were using a for loop in your template. A for loop is designed for iterating over a group of objects (e.g. a QuerySet that would be returned by using a filter()). If you just want to render the values of fields for a single instance, you do not need to use a for loop.
Here is a link to the Django docs, for filter() - which returns a QuerySet (group of objects).
Here is a link to the Django docs, for get() - which returns single object.
since your 'post' variable is pointing to a QuerySet of Post objects you can directly select the first element in the QuerySet as like this :
Reply.objects.create(
post=post[0], detail=comments, author = request.user)
I have the following models in my app
Account
class Account(CommonModel): # Accounts received from Client
client = models.ForeignKey('Client', on_delete=models.RESTRICT)
reference = models.CharField(db_index=True, max_length=50)
def __str__(self):
return f"{self.client} {self.reference}"
Person
class Person(CommonModel):
title = models.CharField(max_length=100,choices=choi.person_title())
name = models.CharField(db_index=True, max_length=100)
birth_date = models.DateField()
def __str__(self):
return f"{self.title} {self.name}"
AccountPerson
class AccountPerson(CommonModel): # Account -> Person link
account = models.ForeignKey("core.Account", on_delete=models.RESTRICT, related_name="accountperson_account")
person = models.ForeignKey("core.Person", on_delete=models.RESTRICT, related_name="accountperson_person")
contact_type = models.CharField(max_length=50, choices=choi.contact_type())
def __str__(self):
return f"{self.account} - {self.person} ({self.contact_type})"
The AccountPerson model holds relationships between accounts and people (one person can have multiple accounts). I'm trying to return a query set containing a list of Accounts, and the Person they're linked to (if any). My background is SQL, so I'm thinking of a query that would hit Account -> AccountPerson --> Person, but I'm stuck.
I've tried prefetch_related() but I'm only returning details in the Account table - I'm unsure of how to access Person from there and put those fields into my HTML file.
View
def account_list(request):
data = Account.objects.all().prefetch_related('accountperson_account')
return render(request, 'core/account_list.html', {'data': data})
account_list.html
Code condensed for readability
...
{% for i in data %}
<tr>
<td>{{i.client}}</td>
<td>{{i.reference}}</td>
{% endfor %}
...
I'm currently in a position where my page loads, and I see the entries in my Account model, but that's it.
Update
I changed my view to this
def account_list(request):
data = AccountPerson.objects.all().select_related('account').select_related('person')
return render(request, 'core/account_list.html', {'data': data})
And I can now access fields in Account and Person in my HTML like so
{% for i in data %}
<tr>
<td>{{i.account.client}}</td>
<td>{{i.account.reference}}</td>
<td>{{i.contact_type}}</td>
<td>{{i.person.name}}</td>
{% endfor %}
I just want to check that this is the right way (or one of them)?
I'd change the datamodel slightly to be more Django-y. Django has the concept of ManyToMany fields which is what you're trying to accomplish. (https://docs.djangoproject.com/en/3.1/ref/models/fields/#django.db.models.ManyToManyField)
You would define the Person model as you did and change the Account model to have a ManyToMany field (you could also switch it around, that won't matter).
You can also defined the intermediate model like you intended. Use the through argument on the ManyToMany for this.
You can use Related Manager to handle all lookups both ways: account.person and person.account (the 'account' part is set by the related_name).
class Account(CommonModel): # Accounts received from Client
client = models.ForeignKey('Client', on_delete=models.RESTRICT)
reference = models.CharField(db_index=True, max_length=50)
person = models.ManyToManyField(Person, through=AccountPerson, related_name='account')
I have created a Django model with the following attributes.
class Info(models.Model):
number = models.IntegerField()
ID = models.IntegerField()
reading = models.IntegerField()
date = models.DateField()
I would like to make it so that when a user searches for an 'ID' or 'number' from the database, they are shown the date and reading. Here is my search results code in views.py:
class SearchResultsView(ListView):
model = Info
template_name = 'search_results.html'
def get_queryset(self):
query = self.request.GET.get('q')
reading_list = Info.objects.filter(
Q(ID__icontains=query) | Q(number__icontains=query)
)
return reading_list
And here is my search_results.html template:
<h1>Search Results</h1>
<ul>
{% for reading in reading_list %}
<li>
{{ reading.reading }}, {{ reading.date }}
</li>
{% endfor %}
</ul>
I am a little confused as to whether I should include a 'str' method in my model. Will the app be able to print the date and reading using just this code?
Based on your current settings, there is no need to add a __str__ function in your model because you are using instance's fields rather than instance itself.
However, if there are any references to the instance itself, e.g. a foreign key to this model or you just want to check the instance itself, adding a __str__ function will increase the readability. You can check the __str__ documentation for details.
Without __str__ field, if you have an Info instance, you will have:
<Info: Info object (1)>. After adding a __str___ function and return str(id) for example, you will see <Info: 1>.
It would be great to have a CharField(e.g. description = models.CharField()) in your Info model if you want to add the __str__ function. Then the representation of this object would be <Info: Good Reading>
Whenever an instance of model is created in Django, it displays the object as ModelName Object(1).to make changes to your Django model using this
def __str__(self):
return str(self.id) #if its integer, make it str
return self.name #if its already str. you dont make it str
it changes the display name from ModelName Object(1) to field name of def __str__(self): in your admin panel.
and one thing def __str__(self) for python 3 and def __unicode__(self): for python 2
please help to understand.
I have the next models :
class TagsList(models.Model):
tags_list = models.CharField(max_length=30)
def __str__(self):
return self.tags_list
class Blog(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
tags = models.ManyToManyField(TagsList)
how i can get related tags by object (in my case object with post_id)?
It's my view file :
def single(request, post_id):
object_post = Blog.objects.get(id=post_id)
tags = TagsList.objects.all()
content = {
'object_post': object_post,
'tags': tags,
}
return render(request, 'single.html', content)
I tried all cases, but how to include to content exactly tags which are related to this object, don't know.
Thanks all, for the help.
P.S. Using django 1.11
initial answer from comments:
In a many-to-many relation you can access the related objects, try this in def single:
tags=object_post.tags.all()
So I'm trying to index some items with Django-Haystack (elasticsearch backend), one of the indexing criteria being tags on the item, which are a m2m relation(I implemented my own custom solution as it was easier for me than using taggit), here is what my models look like.
class GalleryTag(models.Model):
tag = models.CharField(max_length=100, unique=True)
slug = AutoSlugField(populate_from='tag', unique=True)
class Meta:
abstract = True
def __unicode__(self):
return self.tag
class Tag(GalleryTag):
pass
class Artist(GalleryTag):
pass
class Character(GalleryTag):
pass
class Gallery(models.Model):
characters = models.ManyToManyField(Character, blank=True, related_name='characters')
artists = models.ManyToManyField(Artist, blank=True, related_name='artists')
tags = models.ManyToManyField(Tag, blank=True, related_name='tags')
def __unicode__(self):
return self.name
The object I'm trying to index to be searchable is Gallery, and I would like to be able to have the tags, artists, and characters(all the m2ms) be one of the searchable criteria on them. I could not really find anything about how to make relations searchable, the basic examples only use completely flat models. Thanks.
One way to do this would be to pull in the data in the template file of GalleryIndex.
Something like:
{% for s in object.hasTags.all %}
{{t.tag}}
{% endfor %}
If, for whatever reason, resolving your relation is too complex for a template then add a field called tags to GalleryIndex and add a routine prepare_tags(self, obj) that queries the relevant data, concatenates and returns it as a string.