jejy2343
jejy2343

Reputation: 449

NoReverseMatch Error Related to get_context_data

I'm getting a NoReverseMatch error resulting from my template url tag. But I'm using class based views, and the error is related to using the get_context_data function. If I comment out the get_context_data function, I don't get the error.

Here's the error I'm getting:

NoReverseMatch at /task-manager/update-project/e75eac16-711b-4fb7-9b08-7516cae8433f/

Reverse for 'update-project' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['task-manager/update-project/(?P[a-zA-Z0-9_-]+)/$']

And then: Error during template rendering

In template [projectdir]/[appdir]/templates/tasks

/update-project.html, error at line 7
Reverse for 'update-project' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['task-manager/update-project/(?P<pk>[a-zA-Z0-9_-]+)/$']

Here is the update-project.html:

{% extends "tasks/base.html" %}

{% block content %}
<h2>Update a project</h2>

<div class="form">
<form action="{% url 'task_manager:update-project' project.id %}" method="POST">
    {% csrf_token %}
    {{ form }}
    <BR><BR>
    <input type="submit" value="Submit" />
</form>
</div>
....

My application's urlconf is tasks/urls.py:

from django.conf.urls import url
from . import views

urlpatterns = [
    # Index
    url(r'^$', views.TaskView.as_view(), name='index'),

    # TASKS
    # E.g., /task/3j243o-Ofjdsof-3123
    url(r'^tasks/(?P<pk>[0-9a-zA-Z_-]+)/$', views.TaskDetailView.as_view(), name='task_detail'),
    # Adding tasks
    url(r'^add-task/$', views.TaskCreate.as_view(), name='add_task'),
    # Update/view tasks
    url(r'^view-task/(?P<pk>[0-9a-zA-Z_-]+)/$', views.TaskUpdate.as_view(), name='view_task'),

    # PROJECTS
    # E.g., /project/234jf0we-324skl-34j
    url(r'^projects/(?P<pk>[a-zA-Z0-9_-]+)/$', views.ProjectDetailView.as_view(), name='project_detail'),
    # Adding projects
    url(r'^add-project/$', views.ProjectCreate.as_view(), name='add_project'),
    # Updating/viewing Projects
    url(r'^update-project/(?P<pk>[a-zA-Z0-9_-]+)/$', views.ProjectUpdate.as_view(), name='update-project')
]

The relevant part of views.py is:

class ProjectUpdate(UpdateView):
    """
    This will be used to view and update projects
    """
    template_name = 'tasks/update-project.html'
    model = Project
    context_object_name = 'project'
    fields = ['name','status', 'purpose', 'vision', 'big_steps', 'context', 'priority', 'due_date', 'related_project']

    def get_context_data(self, **kwargs):
        """
        This pulls in related tasks to display them as links.
        """
        # Call base implementation first to get a context
        context = super(ProjectUpdate, self).get_context_data(**kwargs)
        # TO DO: Add in querysets of related tasks
        context['related_tasks'] = Task.objects.all()

And relevant part of model.py:

class Project(models.Model):
    """
    Project is for any multi-step thing that needs to be done. Tasks
    will be associated with it.
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    name = models.CharField(max_length=200)

    purpose = models.TextField(blank=True)
    """What is my purpose with this task?"""

    vision = models.TextField(blank=True)
    """Vision refers to what the task will look like when successfully
    completed"""

    big_steps = models.TextField(blank=True)
    """What are the big steps (not task-level steps) that need to be
    completed? Maybe split this out into a new class, similar to tasks"""

    status = models.CharField(max_length=30, choices=STATUSES, default='pending')
    created_date = models.DateTimeField(auto_now_add=True)
    updated_date = models.DateTimeField(auto_now=True)
    context = models.CharField(max_length=50, choices=CONTEXTS)
    priority = models.CharField(max_length=50, choices=PRIORITIES)
    due_date = models.DateTimeField(blank=True, null=True)
    related_project = models.ForeignKey("self", blank=True, null=True)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('task_manager:project_detail', kwargs={'pk': self.pk})

What is weird is that if I comment out the get_context_data function in my view, it works just fine.

Upvotes: 2

Views: 413

Answers (1)

Alasdair
Alasdair

Reputation: 309089

It looks like you have forgotten to return the context. Without the return statement, it implicitly returns None. This causes the reverse match, because the url tag gets None instead of the required project id.

def get_context_data(self, **kwargs):
    """
    This pulls in related tasks to display them as links.
    """
    # Call base implementation first to get a context
    context = super(ProjectUpdate, self).get_context_data(**kwargs)
    # TO DO: Add in querysets of related tasks
    context['related_tasks'] = Task.objects.all()
    return context

Upvotes: 1

Related Questions