Domanda

I'm new to Django and have been stuck on this for a few days now. Hoping to find some help here. I've searched stackoverflow and read through the django docs but haven't been able to grasp this. I'm using Django 1.6.2 and Python 2.7.

I'm setting up a simple news app in which article has a ManyToMany relationship with category. I'm running into trouble trying to display articles from a specific category. I have the index working displaying all articles and also the single page view is working e.g. clicking on article title from index brings you to the article itself. Once in the article I am displaying the article category. Up to here all is well. When I try to link the category and display an index for all posts in that category I get a NoReverseMatch for the url 'category-archive'.

Should I do this in a view like I'm trying or would the Manager work better? Open to all suggestions and answers. Like I said I'm new so would like to know best practice. Here is my code and thank you in advance for dealing with a noobie.

models.py

from django.db import models
from tinymce import models as tinymce_models

    class ArticleManager(models.Manager):
        def all(self):
        return super(ArticleManager, self).filter(active=True)

    class Category(models.Model):
        title = models.CharField(max_length=65)
        slug = models.SlugField()

    def __unicode__(self, ):
        return self.title

    class Article(models.Model):
        title = models.CharField(max_length=65)
        slug = models.SlugField()
        description = models.CharField(max_length=165)
        content = tinymce_models.HTMLField()
        categories = models.ManyToManyField(Category)
        image = models.ImageField(upload_to='article/images')
        active = models.BooleanField(default=False)
        timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
        updated = models.DateTimeField(auto_now=True, auto_now_add=False)

    objects = ArticleManager()

    def __unicode__(self, ):
        return self.title
    class Meta:
        ordering = ['-timestamp',]

views.py

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, RequestContext, get_object_or_404

from .models import Article, Category

def all_articles(request):
    articles = Article.objects.all()
     return render_to_response('news/all.html', locals(),   context_instance=RequestContext(request))

def single_article(request, slug):
    article = get_object_or_404(Article, slug=slug)
    return render_to_response('news/single.html', locals(), context_instance=RequestContext(request))

def category_archive(request, slug):
    articles = Article.objects.filter(category=category)
    categories = Category.objects.all()
    category = get_object_or_404(Category, slug=slug)
    return render_to_response('news/category.html', locals(),    context_instance=RequestContext(request))

single.html - for single article view

{% extends 'base.html' %}
{% block content %}

    <h1>{{ article.title }}</h1>
    <img src='{{ MEDIA_URL }}{{ article.image }}' class="article-image img-responsive"/>
    <p>{{ article.content|safe }}</p>
    <p class='small'>
**this next line gets an error for the url 'category-archive'**
    {% for category in article.categories.all %}Category: <a href='{% url "category-archive" %}{{ category.slug }}'>{{ category }}</a>{% endfor %}</p>

{% endblock %}

category.html - display all articles in specific category

{% extends 'base.html' %}


{% block content %}

    {% for article in articles %}
    <h1><a href='{% url "articles" %}{{ article.slug }}'>{{ article }}</a></h1>
    <a href='{% url "articles" %}{{ article.slug }}'><img src='{{ MEDIA_URL }}{{ article.image }}' class="img-responsive"/></a>
    {{ article.description }}

    {% if forloop.counter|divisibleby:4 %}
     <hr/>
    <div class='row'>
    {% endif %}
    {% endfor %}
    </div>

{% endblock %}

urls.py - project urls

from django.conf.urls import patterns, include, url 
from django.conf import settings
from filebrowser.sites import site

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',


(r'^tinymce/', include('tinymce.urls')),
(r'^admin/filebrowser/', include(site.urls)),
(r'^grappelli/', include('grappelli.urls')),

(r'^static/(?P<path>.*)$', 'django.views.static.serve',{
    'document_root': settings.STATIC_ROOT
    }),
(r'^media/(?P<path>.*)$', 'django.views.static.serve',{
    'document_root': settings.MEDIA_ROOT
    }),

url(r'^admin/', include(admin.site.urls)),    
url(r'^$', 'dl.views.home', name='home'),
(r'^news/', include('news.urls')),
(r'^guides/', include('guides.urls')),


)

urls.py - news urls

from django.conf import settings
from django.conf.urls import patterns, include, url


urlpatterns = patterns('news.views',
    url(r'^$', 'all_articles', name='articles'),
    url(r'^(?P<slug>[-\w]+)/$', 'single_article'),
**This next one is giving me the problem I suspect - should be url to category with articles**
    url(r'^chive/(?P<slug>[-\w]+)/?', 'category_archive', name='category-archive'),

)
È stato utile?

Soluzione

I would have post it as a comment but i don't have the reputation. I think that the thing is that the URL Dispatcher expects the category-archive to also get the slug. so you should change the URL in the template to:

{% url "category-archive" category.slug %}

hope this helps!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top