Giorgos Kavalieratos
Giorgos Kavalieratos

Reputation: 455

NoReverseMatch in Django 2

I'm kinda new at this, and I believe I have misunderstood some things so I'll try to describe it as best possible.

I have 3 tables(models), Game, Chapter, Thread. Chapter and Thread are connected with the Game table.

models.py

class Game(models.Model):
    title = models.CharField(max_length=100)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

class Chapter(models.Model):
    title = models.CharField(max_length=80)
    content = models.CharField(max_length=10000, null=True)
    game = models.ForeignKey(Game, on_delete=models.CASCADE)

    def __str__(self):
        return self.chapter

class Thread(models.Model):
    title = models.CharField(max_length=100)
    content = models.CharField(max_length=1000, null=True)
    game = models.ForeignKey(Game, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

views.py

def chapter(request, game_id):
    auth = top_menu = True
    chapters = Chapter.objects.filter(game=game_id)
    return render(request, 'chapters.html', {"chapters": chapters, "auth": auth, "top_menu": top_menu})

def thread(request, game_id):
    auth = top_menu =True
    threads = Thread.objects.filter(game=game_id)
    return render(request, 'threads.html', {"auth": auth, "threads": threads, "top_menu": top_menu})

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index, name="index"),
    path('signup/', signup, name="signup"),
    path('logout/', logout_view, name="logout"),
    path('login/', login_view, name="login"),
    path('<int:game_id>/chapters/', chapter, name="chapter"),
    path('<int:game_id>/threads/', thread, name="thread"),
]

index.html

{% extends 'base.html' %}

{% block content %}
    <div class="container">
        <div class="wrapper">
            <div class="row">
                <div class="col-lg-12 text-center" style="margin-bottom:80px;">
                    <h1>Welcome to Solo Rpg Helper</h1>
                </div>
            </div>
            {% if auth %}
            <div class="row">
                <div class="col-lg-12 text-center">
                    <h1>Your games:</h1>
                    <ul class="list-group list-group-flush">
                        {% for game in games.all %}
                            <a href="{% url 'chapter' game.id %}"><li class="list-group-item">{{ game.title }}</li></a>
                        {% endfor %}
                    </ul>
                </div>
            </div>
            {% else %}
            <div class="row">
                <div class="col-lg-12 text-center sign-buttons">
                    <h3><a href="{% url 'login' %}" class="btn btn-lg btn-success">Sign in</a> <a href="{% url 'signup' %}" class="btn btn-lg btn-danger">Sign up</a></h3>
                </div>
            </div>
            {% endif %}
        </div>
    </div>
{% endblock %}

chapter.html

{% extends 'base.html' %}

{% block top_menu %}
    <li><a href="{% url 'index' %}">Games</a></li>
    <li><a href="{% url 'chapter' 1 %}">Chapters</a></li>
    <li><a href="{% url 'thread' 1 %}">Threads</a></li>
{% endblock %}
{% block content %}
    <div class="container">
        <div class="wrapper">
            {% for chapter in chapters.all %}
                <div class="row">
                    <div class="col-lg-6">
                        <h1>{{ chapter.title }}</h1>
                    </div>
                    <div class="col-lg-6">
                        <p>{{ chapter.content }}</p>
                    </div>
                </div>
            {% endfor %}
        </div>
    </div>
{% endblock %}

index.html works fine because I loop the games so I can access game.id.

In the chapter.html I want to use again game.id but I'm not sure how to access it although it is passed in the function chapter in the views.py (I can see it in the terminal).

If I use it like this:

<li><a href="{% url 'chapter' 1 %}">Chapters</a></li>

it works, but if I use game.id as in index.html:

<li><a href="{% url 'chapter' game.id %}">Chapters</a></li>

I get the error:

Error:

I'm sorry for the long post.

Upvotes: 0

Views: 34

Answers (1)

Alasdair
Alasdair

Reputation: 308939

def chapter(request, game_id):
    auth = top_menu = True
    chapters = Chapter.objects.filter(game=game_id)
    return render(request, 'chapters.html', {"chapters": chapters, "auth": auth, "top_menu": top_menu})

You can't use game.id in the chapters.html template at the moment, because the view doesn't include game in the context dictionary.

A typical approach is to use get_object_or_404, to handle the case when no game matches game_id.

from django.shortcuts import get_object_or_404

def chapter(request, game_id):
    auth = top_menu = True
    game = get_object_or_404(Game, pk=game_id)
    chapters = Chapter.objects.filter(game=game_id)
    return render(request, 'chapters.html', {"chapters": chapters, "auth": auth, "top_menu": top_menu, "game": game})

Upvotes: 2

Related Questions