Failure to get data from database and onto template.

57 views
Skip to first unread message

Malik Rumi

unread,
Oct 1, 2014, 4:32:14 PM10/1/14
to django...@googlegroups.com

Executive Summary:

I need to know how to consistently write fbv’s that get the content I want out of my database and into my templates for display on my site in the way I want it displayed.

I confess, I don’t get it. Mark me down in points for asking a dumb question. I don’t care. I need help.

 

Problem 1

I have successfully constructed my own function based view for listing all my articles with all their sections in a table of contents. At first they were not in order. I put an orderby on the models meta but that made no difference. Then I put an order_by ID in the view and that worked – except they were descending instead of ascending. Then I put reversed on the template and it worked.

 However, in the course of struggling with Problem 2, suddenly my table of contents is out of order again, and I have not touched those lines of code. I don’t understand how that could be. Daniel Roseman suggested I create a new field, number it, and order by that instead of relying on the ID as PK, and I will do that if I have to, but right after that is when I discovered reversed so I didn’t do it then. Now I’d like to know why the order changed when I haven’t touched the code that (supposedly) fixed it.

 Template for loop code:

{% for a in A %}

 

   
{% if a.sections_set.all %}

       
<h1><li>{{ a.name }} {{ a.popular_name }}</li></h1>

           
{% for section in a.sections_set.all reversed %}


 Model meta:

  class meta:

 

        ordering
= ['id']


 View:

def TOC(request):

 

    A
= Articles.objects.order_by('id')

   
for a in A:

        a
.sections_set.order_by('id')

   
return render(request, 'statute.html', {'A': A,})


 

Problem 2 (the bigger one)

I cannot for the life of me get any articles or sections to come up on their own detail page. If I mouse over the links in my table of contents, the little preview url in the bottom right corner comes up correct for each one. I have bounced around from name error to type error to no match errors to does not exist errors and back again.

I have read the documentation. I have done the polls tutorial. I have read about context.  None of that matters. I have researched, tried this that and the other thing, and gotten nowhere. I have no doubt that it is something simple but simple or not I’m not getting it. If you can show me how to get it right, and keep getting it right consistently as I go forward, I would be very grateful.

Yes, I know there are class based views. I read that I can subclass them. But I fail to see the advantage of subclassing something I understand even less over learning to write what I want directly. I can’t learn without understanding, and to do that I need to get my hands dirty writing the code, not relying on someone else’s magic. I am not interested in a flame war as to whether or not CBV’s were a good idea, but I will point out that there is almost zero documentation or tutorials on how to write your own FBV’s, and certainly nothing on any complex FBV. I’ve been searching for over a week for it.

The template I am calling does come up. It overwrites base in all the places I expect it to. But there is no content. Debug toolbar says it is the right view. The only sql queries are sessions and user. Shouldn’t there be at least one for the content? The context processors say my GET querydict is empty and my content is an empty string. The only fields I want to show on the detail pages are the name and the text. Here is the relevant portion of my template:

{% block content %}

 

<div>

{{ text }}

</div>

{% endblock content %}


(I tried {{a.text}} earlier, that didn’t work either.)

Here is my urls.py

urlpatterns = patterns('',

 

url
(r'^$', views.TOC, name='TOC'),

url
(r'^(?P<id>\d+)\/(?P<slug>[-\w]+)', views.articleView, name='articleView'),

url
(r'^(?P<id>\d+)\/(?P<slug>[-\w]+)', views.sectionView, name='sectionView'),

)


 

Here is my most recent attempt at a view:

 def articleView(request, **kwargs):

 

    a
= Articles.objects.values('name', 'text')

    context
= {'a' : a}

   
return render(request, 'statute2.html', context)


Note that this is exactly the same format as laid out in Polls Tutorial 3: https://docs.djangoproject.com/en/1.7/intro/tutorial03/#a-shortcut-render

The only difference is the presence of **kwargs. I was getting all kinds of errors before I tried **kwargs, and I was getting all kinds of errors with GET before I tried values(). Now I just have a blank template, which I also had at various times before **kwargs and values().

 

Daniel Roseman

unread,
Oct 2, 2014, 9:36:59 AM10/2/14
to django...@googlegroups.com
No, what you have done is not exactly what is in the tutorial. 

For a start, you have not taken on board the difference between the view that shows the list of items, and the view that shows the detail for an individual item. `values` returns a list (actually a list of dicts), so in order to show the text of each item you would need to iterate through the list in your template. But that doesn't seem to be what you want to do - you want to show the detail for one individual article. So, you need to query for that article explicitly, by passing in the id and/or the slug from the URL (and that is another difference between what you have done and what is shown in the tutorial), and then using `get()` on the article manager.

(Note you wouldn't normally use `values` here: it's better to pass the full Article object each time.)

So, the view looks like this:

def article_view(request, id, slug):
    article = Article.objects.get(pk=id, slug=slug)
    return render(request, 'statute2.html', {'article': article}

and the template:

{% block content %}
<div> 
{{ article.text }} 
</div> 
{% endblock content %}

--
DR.

Collin Anderson

unread,
Oct 2, 2014, 1:49:47 PM10/2/14
to django...@googlegroups.com
For the ordering issue, I'd recommend setting ordering = ['pk'] in the Model class Meta, then you don't need to try to handle it in your view.

What does your sectionView look like? Does /{{ id }}/{{ slug }}/ uniquely identify both an article and a section, or should it be /{{ article_id }}/{{ article_slug }}/{{ section_id }}/ ?

Malik Rumi

unread,
Oct 2, 2014, 5:01:00 PM10/2/14
to django...@googlegroups.com
Daniel,
Thank you. Yes, your code works. If I had posted a week ago, I would not have lost a week on my life expectancy. Obviously, I'm just not 'getting it'. If you have any suggestions, or resources, to help me understand better going forward, I'd be grateful, but you've done plenty already. Thx.

Malik Rumi

unread,
Oct 2, 2014, 5:08:24 PM10/2/14
to django...@googlegroups.com
Collin, 
Thank you for the suggestion. I will try it tonight after I get off work and can finish cleaning up the code following Daniel's answer. sectionView is supposed to be id/slug, but I included the Article name in the Section names, because I can't put a fk in the slug. So maybe that was also a newby mistake. This must be why Django is sending Article 1 and Article 2 Section 1 to the same view, it sees the match for 'Article' and stops there. So I'll probably end up renaming them, so as you can see, I have (made for myself) a lot of (re)work to do. But I am learning! 

Malik Rumi

unread,
Oct 3, 2014, 7:09:27 PM10/3/14
to django...@googlegroups.com
I just wanted to report back and see if you had any additional ideas to offer. I did change the meta from id to pk, but there was no change. Then I took reverse off the template for loop and (almost) everything was the way I wanted it. For some reason, Article 4 came out Sections 3,4,1,2, in that order. Their ids, in that same order, are 16, 15, 13, 14. In other words, if they were ordered by pk like the rest, they would be in proper order, but they are not. Since it is only this one group, I don't want to mess with the whole thing anymore, but I don't know what to do about these. The only thing I can think of is to delete 3 and 4 and then re-create them and hope that puts them in the right order. Any other ideas?

I was wrong about the Articles and Sections on the same view. Turns out it was the ID that was controlling everything, Django wasn't even looking at the slug, even when I put unique_together on the meta. Changing the names of the Sections didn't even work. Neither did putting article_id in the Sections regex. If I put sectionView first in the urlconf, all the sections would come up fine but none of the articles. If I put articleView first in the urlconf, the articles all came up and the sections got doesnotexist. The only thing that worked (and I tried A LOT of variations) was to put the Sections on (?P<slug>) only, no id, no digits.

So even though that problem is technically solved, if you have some best practices to share with me so I can get this done better next time, I am all ears. 

Thanks again for all the help.

Collin Anderson

unread,
Oct 5, 2014, 9:00:47 AM10/5/14
to django...@googlegroups.com
The only thing I can think of is to delete 3 and 4 and then re-create them and hope that puts them in the right order. Any other ideas?
That should work just fine, as long as you only add at the end in the future. If it becomes an issue more, you may want to consider adding an "order" or "ranking" column so you have more control.
 
I was wrong about the Articles and Sections on the same view. Turns out it was the ID that was controlling everything, Django wasn't even looking at the slug, even when I put unique_together on the meta. Changing the names of the Sections didn't even work. Neither did putting article_id in the Sections regex. If I put sectionView first in the urlconf, all the sections would come up fine but none of the articles. If I put articleView first in the urlconf, the articles all came up and the sections got doesnotexist. The only thing that worked (and I tried A LOT of variations) was to put the Sections on (?P<slug>) only, no id, no digits.
I think what you are looking for is something like this:

 url(r'^(?P<id>\d+)\/(?P<slug>[-\w]+)', views.article_or_section_view, name='article_or_section_view'),


def article_or_section_view(request, **kwargs):
   
try:
        article
= Article.objects.get(pk=id, slug=slug)
       
return render(request, 'statute2.html', {'article': article)
   
except Article.DoesNotExist:
       
pass
   
try:
        section
= Section.objects.get(pk=id, slug=slug)
       
return render(request, 'statute2.html', {'section': section)
   
except Section.DoesNotExist:
       
pass
   
raise Http404('no article or section matches that id and slug')


Though Django's unique_together only applies to that one model. If you post roughly what your models are we could give more pointers.

I personally have found it helpful to re-use the same model using something like this:
class Content(models.Model):
    type
= models.CharField(max_length=30, choices=[('article', 'Article'), ('section', 'Section')])
    title
= models.CharField(max_length=255)
    slug
= models.CharField(max_length=255)
    content
= models.TextField()
    parent
= models.ForeignKey('self', blank=True, null=True, help_text='example: article of a section')



    
Reply all
Reply to author
Forward
0 new messages