Defining Views and URLs for Many to Many field in Django
Question: 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'),
    
    )
    


Answer: 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!

