Omar Elweshy
Omar Elweshy

Reputation: 180

No Reverse Match at

I try to redirect to question detailView after answer on question but i get

NoReverseMatch at /98afdfc7-df41-416c-aaae-c1014bfbf119/answer

Reverse for 'question_detail' with arguments '('87',)' not found. 1 pattern(s) tried: ['questions/(?P[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$']

after entering my answer

models

class Question(models.Model):
    id = models.UUIDField(_("ID"), primary_key=True,
                          default=uuid.uuid4, editable=False)
    question = models.CharField(_("Question"), max_length=300)


    def get_absolute_url(self):
        return reverse('question_detail', args=[str(self.id)])


class Answer(models.Model):
    question = models.ForeignKey(Question, verbose_name=_(
        "Answer"), on_delete=models.CASCADE, related_name='answers')
    answer = models.CharField(max_length=255)


    def get_absolute_url(self):
        return reverse('question_detail', args=[str(self.id)])

Urls

urlpatterns = [
    path('<uuid:pk>/answer', AnswerQuestionView.as_view(), name='answer'),
    path('questions/<uuid:pk>', QuestionDetailView.as_view(),
         name='question_detail'),
]

Views

class AnswerQuestionView(CreateView):
    model = Answer
    context_object_name = 'answer'
    fields = ['answer', 'question']
    template_name = "forms/answer.html"
   

class QuestionDetailView(DetailView):
    model = Question
    context_object_name = 'question'
    template_name = "question_detail.html"

HTML form

<form method="post">
    {% csrf_token %}
{{form.as_p}}
<button value="submit">Post</button>
</form>

Upvotes: 1

Views: 97

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476729

The id of your answer is not a UUID. Indeed, in your Answer model you did not specify a primary key, and in that case Django automatically adds a primary key that is an AutoField:

By default, Django gives each model the following field:

id = models.AutoField(primary_key=True)

This thus means that self.id of an Answer (not a Question), is an int, and thus this will not match with the uuid path converter of the path:

urlpatterns = [
    path(
        '<uuid:pk>/answer/',
        AnswerQuestionView.as_view(),
        name='answer'
    ),
    path(
        'questions/<int:pk>/',  # ← use int, not uuid
        QuestionDetailView.as_view(),
        name='question_detail'
    ),
]

You can also try to migrate the data to use a uuid instead, but since there is already data, migrating will be more painful.

EDIT: It looks however that your get_absolute_url of the Answer aims to refer to the detail view of the Question. Since a get_absolute_url() should return a canonical url, this is not really how a get_absolute_url() is supposed to work.

If you want to specify the id of the Question, then you use:

class Answer(models.Model):
    # …
    
    def get_absolute_url(self):
        return reverse('question_detail', args=(self.question_id,))

In that case of course the path should use the uuid.

Upvotes: 1

Related Questions