I have a database table that allows you to enter details about a particular person. How can i then list all the entries of that table to show all the people added to the database.
urls.py
url(r'^accounts/loggedin/locations/all/$', 'assessments.views.locations'),
url(r'^accounts/loggedin/locations/get/(?P<location_id>\d+)$', 'assessments.views.location'),
url(r'^accounts/loggedin/locations/create/$', 'assessments.views.create'),
models.py
class People(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
view.py
def people(request):
return render_to_response('dashboard/people.html', {'people': People.objects.all})
people.html
<body>
<h1>People</h1>
{% for p in people %}
<h1>{{ people.first_name }}</h1>
{% endfor %}
</body>
</html>
Two problems:
you should call all() to get the results, note the ():
People.objects.all()
in the template, you should use {{ p.first_name }} instead of {{ people.first_name }} since you are iterating over people variable which is a QuerySet - a list of objects, basically
it is same question with this link
If you had the Question model below,
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField(verbose_name='date published')
Through this code, you can see all entries (or fields, features).
fields = Question._meta.get_fields()
thanks.
Related
I have two models that look like;
class Body(models.Model):
body_id = models.AutoField(primary_key=True)
is_adult = models.BooleanField(default=False)
body = models.TextField()
add_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
add_date = models.DateTimeField()
edit_user = models.CharField(max_length=25, blank=True, null=True)
edit_date = models.DateTimeField(blank=True, null=True)
category = models.ForeignKey(Category, models.CASCADE)
class Meta:
managed = True
db_table = 'jdb_body'
class BodyTag(models.Model):
body_tag_id = models.AutoField(primary_key=True)
body = models.ForeignKey('Body', models.CASCADE)
tag = models.ForeignKey('Tag', models.CASCADE, db_column='tag')
class Meta:
managed = True
db_table = 'jdb_body_tag'
def __str__(self):
return self.tag
I have a view that looks like;
def index(request):
latest_body_list = Body.objects.all().order_by('-body_id')
context = {
'latest_body_list': latest_body_list
}
return render(request, 'index.html', context)
That view gives me a list Body records no problem. I am trying to display Body records with their corresponding BodyTag records. What am I doing wrong?
You neeed a ManyToManyField in your class Body
tags = models.ManyToManyField('Tag')
To access
body = Body.objects.get(body_id=1)
tags = body.tags.all()
EDIT
My previous answer was incorrect because I did not see the more complex relationship. The problem is this: You have many BodyTag objects to one Body object, but you also have many BodyTag objects to one Tag object. So as shown in the image, BodyTag's BT4 and BT5 belong to Body's BODY1 and BODY2. That's why #chipchap31 is talking of a ManyToMany relationship.
If this is not the relationship you want, and from your comments I do not think that you want a ManyToMany field, then the BodyTag model should be either changed, or perhaps discarded. Perhaps relate Body to Tag directly using the ForeignKey, and then have a field in the Tag model that distinguishes it with the type of tag it is, so one type would be body, and you can use a choices field to show all the different types of Tags.
Previous answer (Incorrect)
If you mean displaying these in your template, then all you have to do is follow the ForeignKey relationship backwards. This is shown in the documentaion for the views, but it would look pretty much the same in the template. Something like:
{% for body in latest_body_list %}
{{ body }}
{% for tag in body.tag_set.all %}
{{ tag }}
{% endfor %}
{% endfor %}
The -set is what tells django to look backward in the ForeignKey relationship.
A perhaps better way, also shown in the documentation would be to define a related_name in your ForeignKey:
class BodyTag(models.Model):
body_tag_id = models.AutoField(primary_key=True)
body = models.ForeignKey('Body', models.CASCADE, related_name='tags')
tag = models.ForeignKey('Tag', models.CASCADE, db_column='tag')
Then your template could be written a little better:
{% for body in latest_body_list %}
{{ body }}
{% for tag in body.tags.all %}
{{ tag }}
{% endfor %}
{% endfor %}
I am Building a BlogApp and I stuck on a Problem. I am trying to access two model objects but Failed many times.
models.py
class Topic(models.Model):
topic_no = models.CharField(max_length=100,default='')
topic_title = models.CharField(max_length=200,default='')
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(Profile,on_delete=models.CASCADE,null=True)
def __str__(self):
return self.dairy_title
class Entry(models.Model):
topic = models.ForeignKey(Topic, on_delete=models.CASCADE,default='',related_name='topic')
date_added = models.DateTimeField(auto_now_add=True,null=True)
updated = models.DateTimeField(auto_now=True)
note = models.TextField()
def __str__(self):
return str(self.topic)
views.py
def show_entry(request):
showd = Entry.objects.all()
context = {'showd':showd}
return render(request ,'mains/showd.html', context)
showd.html
{% for post in topic.journel_set.all %}
{{ post.topic_title }}
{{ post.note }}
{% endfor %}
The Problem
I am trying to access both model's Objects in showd.html.
What have i tried
I saw tons of Answers like :- This This and Many More answers about reverse related object lookup. BUT nothing is worked for me.
I don't know am i doing wrong in this.
Any help would be Appreciated.
Thank You in Advance.
Entry has ForeignKey towards Topic it is not reverse accessor so Entry has only one Topic
So you could for instance do
{% for entry in showd %}
{{ entry.topic.topic_title }}
{{ entry.note }}
{% endfor %}
My django loop in the templates does not work correctly. Why, because of me, everything looks good?
Any help will be appreciated.
My models.py
class Tags(models.Model):
name = models.CharField(max_length=10)
class Person(models.Model):
keywords = models.ForeignKey(Tags, on_delete=models.CASCADE)
My views.py
def person_detail(request, user_id):
person = get_object_or_404(Person, pk=user_id)
context = {'person': person}
return render(request, 'person_detail.html', context)
My templates.html
{% for tag in person.tags %}
<span class="badge badge-lg badge-pill badge-info"># {{ person.tags.name } </span>
{% endfor %}
This gives no results even though there is data in the database.
You are doing it backwards. Your Tags model should have a foreign key to Person, not the other way around. For example:
class Person(models.Model):
...
class Tag(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
name = models.CharField(max_length=10)
Note that I've also renamed your Tags model to Tag as it makes sense to name models singular.
Then you can write the following:
{% for tag in person.tag_set.all %}
...
{% endfor %}
I have a models.py file containing this:
class Entry(models.Model):
text = models.TextField(default='')
time_created = models.DateTimeField(auto_now=False, auto_now_add=True)
time_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
abstract = True
#rest of code ...
class Question(Entry):
def get_absolute_url(self):
return reverse('view_question', args=[self.id])
class Answer(Entry):
question = models.ForeignKey(Question, on_delete=models.CASCADE, default=None)
By using Django-debug-toolbar I found out that I am duplicating many SQL queries.
What I am trying to do is get the last 5 questions asked, and display them in my home page, along with some more data containing Answers to those questions, the user who provided the answer, avatar of that user and etc and etc...
I am currently doing that with this views.py and home.html template:
views.py:
#login_required(login_url="accounts/login/")
def home_page(request):
last_five = Question.objects.all().order_by('-id')[:5]
last_five_in_ascending_order = list(reversed(last_five))
return render(request, 'home.html', {
'question_list': last_five_in_ascending_order,
})
home.html:
{% for question in question_list %}
{{ question.text }}
{% if question.answer_set.all %}
{% for answer in question.answer_set.all %}
<img src="/media/{{ answer.created_by.userprofile.avatar }}" alt="">
<a href="{% url 'profile' answer.created_by.id %}">
{% firstof answer.created_by.get_full_name answer.created_by.username %}
</a>
{{ answer.time_passed }}
{{ answer.text | safe }}
{% endfor %}
{% endif %}
{% endfor %}
How can I decrease my sql queries to the database?
And should I really be worried about these things? Do they make a difference for a website with little user activity?
What you have here is table inheritance rather than a simple many to one relationship and that makes like really complicated. I don't really see why a simple setup like this needs table inheritance here. Modifying your models like this works just as well
class Entry(models.Model):
text = models.TextField(default='')
time_created = models.DateTimeField(auto_now=False, auto_now_add=True)
time_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
abstract = True
#rest of code ...
class Question(models.Model):
entry = models.OneToOneField(Question)
def get_absolute_url(self):
return reverse('view_question', args=[self.id])
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE, default=None)
entry = models.OneToOneField(Question)
To solve your issue of many queries being executed. We now resort to select_related
Question.objects.select_related('entry)
Answer.objects.select_related('entry', 'question')
The debug toolbar will now show that repetitive queries have been eliminated.
should I really be worried about these things? Do they make a
difference for a website with little user activity?
No all those queries are attempts to fetch related objects by their primary key. In any database, a lookup on a single item with a primary key is O(log (N)). But the base of the logarithm is usually a so you need not be concerned.
If you fetched them all at once it would be of course be faster since you are now having a single O(log (N)) operation with larger constants. But whether the difference is noticeable on a small site is debatable.
I have a django application where I have few manytomany fields and im trying to show these relation records in my listing, however it all comes blank
so this is my model:
class Genre(models.Model):
genre_name = models.CharField(max_length=50)
genre_slug = models.SlugField(max_length=300)
genre_meta = models.TextField(max_length=300)
genre_description = models.TextField(max_length=300)
listing = models.BooleanField(default=True)
def __unicode__(self):
return self.genre_name
class Movie(models.Model):
movie_name = models.CharField(max_length=50)
movie_slug = models.SlugField(max_length=300)
movie_description = models.TextField(null=True, max_length=300)
movie_category = models.ManyToManyField(Category, related_name='category')
movie_genre = models.ManyToManyField(Genre, blank=True, related_name='genre')
listing = models.BooleanField(default=True)
def __unicode__(self):
return self.movie_name
this is my view
def AllMovies (request):
movies= Movie.objects.all().order_by('movie_name')
context = {'movies': movies}
return render_to_response('all.html', context, context_instance=
RequestContext(request))
and this is my template
{% for movie in movies %}
{{ movie }}
{% for genre in movies.genre.all %}{{ genre_name }}{% endfor %}
{% endfor %}
so there are three concerns here:
1- All I get is blank in my template
2- What would be the best option to show items which have been ticked as listed and hide the rest in template
3- This is a data bank so im sure we will need to use load more button in my template, but if i want to show 30 of items instead of all
Try this:
{% for movie in movies %}
{{ movie }}
{% for genre in movie.movie_genre.all %}{{ genre_name }}{% endfor %}
{% endfor %}
You were trying to iterate over movies.genre.all, which is wrong because:
movies is a queryset, you should use movie instead, as it is a Model instance
genre is not a field in the Movie model, you should use movie_genre, which is a ManyToManyField you are looking for
I believe you didn't understand the related_name attribute. It doesn't modify the behavior of the field (in this case: movie_genre). Instead, it changes the name of an attribute in a related model (in this case: Genre). For example, you can use it to get all related movies:
>>> genre = Genre.objects.get(name='Drama')
>>> genre.genre.all()
[<Movie>, <Movie>, ...]
As you can see, your choice of a related_name wasn't so good. Something like movies would be more appropriate.
Please, read the documentation once again, as you probably didn't understand Django's logic around relations (foreign keys, many-to-many, etc.).
Besides, here are a few style-related tips:
don't use movie_ and genre_ prefixes in field names - e.g. it is obvious that genre_name is a name of a genre, since it is defined inside Genre model
try to follow PEP8 (http://legacy.python.org/dev/peps/pep-0008/), as it is a standard in the Python community
read about class-based views (https://docs.djangoproject.com/en/dev/topics/class-based-views/) - you may find them very helpful