Django Reverse for ' ' with arguments '('',)' not found

2k views Asked by At

I have a problem while using Django. I was trying to create a learning_log web application from my book and came across this error: NoReverseMatch at /edit_entry/8/ Reverse for 'topic' with arguments '('',)' not found. 1 pattern(s) tried: ['topics/(?P<topic_id>[0-9]+)/\Z']. It said it was because of this line in my edit_entry.html file: p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p> but I checked my entire project and couldn't find the reason, Here is my urls.py:

from django.urls import path

from . import views

app_name = 'learning_logs'
urlpatterns = [
    path('', views.index, name='index'),
    path('topics/', views.topics, name='topics'),
    path('topics/<int:topic_id>/', views.topic, name='topic'),
    path('new_topic/', views.new_topic, name='new_topic'),
    path('new_entry/<int:topic_id>/', views.new_entry, name='new_entry'),
    path('edit_entry/<int:entry_id>/', views.edit_entry, name='edit_entry'),
]

views.py:

from django.shortcuts import render, redirect
from .models import Topic, Entry
from .forms import TopicForm, EntryForm
def index(request):
    """The home page for Learning Log."""
    return render(request, 'learning_logs/index.html')
def topics(request):
    """Show all topics."""
    topics = Topic.objects.order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)
def topic(request, topic_id):
    """Show a single topic and all its entries."""
    topic = Topic.objects.get(id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries':entries}
    return render(request, 'learning_logs/topic.html', context)
def new_topic(request):
    """Add a new topic."""
    if request.method !='POST':
        form = TopicForm()
    else:
        form = TopicForm(data=request.POST)
        if form.is_valid():
            form.save()
            return redirect('learning_logs:topics')

    context = {'topic': topic, 'form': form}
    return render(request, 'learning_logs/new_entry.html', context)
def edit_entry(request, entry_id):
    """Edit and existing entry."""
    entry = Entry.objects.get(id=entry_id)
    topic = entry.topic

    if request.method !='POST':
        form = EntryForm(instance=entry)
    else:
        form = EntryForm(instance=entry, data=request.POST)
        if form.is_valid():
            form.save()
            return redirect('learning_logs:topic', topic_id=topic.id)

   context = {'entry': entry, 'topic': topic, 'form': form}
   return render(request, 'learning_logs/edit_entry.html')

models.py:

from django.db import models

class Topic(models.Model):
    """A topic the user is learning about."""
    text = models.CharField(max_length=200)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        """Return a string representation of the model."""
        return self.text

class Entry(models.Model):
    """Something specific about a learned topic."""
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = 'entries'

    def __str__(self):
        """Return a string representation of the model."""
        return f"{self.text[:50]}..."

forms.py:

from django import forms

from .models import Topic, Entry

class TopicForm(forms.ModelForm):
    class Meta:
        model = Topic
        fields = ['text']
        labels = {'text': ''}

class EntryForm(forms.ModelForm):
    class Meta:
        model = Entry
        fields = ['text']
        labels = {'text': ''}
        widgets = {'text': forms.Textarea(attrs={'cols': 80})}

base.html:

<p>
  <a href="{% url 'learning_logs:index' %}">Learning Log</a>
  <a href="{% url 'learning_logs:topics' %}">Topics</a>
</p>

{% block content %}{% endblock content %}

topics.html:

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

{% block content %}

  <p>Topics</p>

  <ul>
    {% for topic in topics %}
      <li>
        <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
      </li>
    {% empty %}
      <li>No topics have been added yet.</li>
    {% endfor %}
  </ul>

  <a href="{% url 'learning_logs:new_topic' %}">Add a new topic</a>

{% endblock content %}

new_topic.html:

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

{% block content %}
  <p>Add a new topic:</p>

  <form action="{% url 'learning_logs:new_topic' %}" method='post'>
    {% csrf_token %}
    {{ form.as_p }}
    <button name="submit">Add topic</button>
  </form>

{% endblock content %}

new_entry.html:

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

{% block content %}

  <p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>

  <p>Add a new entry:</p>
  <form action="{% url 'learning_logs:new_entry' topic.id %}" method='post'>
    {% csrf_token %}
    {{ form.as_p }}
    <button name='submit'>Add entry</button>
  </form>

{% endblock content %}

topic.html:

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

{% block content %}

  <p>Topic: {{ topic }}</p>

  <p>Entries:</p>
  <p>
    <a href="{% url 'learning_logs:new_entry' topic.id %}">Add new entry</a>
  <ul>
    {% for entry in entries %}
      <li>
        <p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
        <p>{{ entry.text|linebreaks }}</p>
        <p>
          <a href="{% url 'learning_logs:edit_entry' entry.id %}">Edit entry</a>
        </p>
      </li>
    {% empty %}
      <li>There are no entries for this topic yet.</li>
    {% endfor %}
  </ul>

{% endblock content %}

edit_entry.html:

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

{% block content %}

  <p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>

  <p>Edit entry</p>

  <form action="{% url 'learning_logs:edit_entry' entry.id %}" method='post'>
    {% csrf_token %}
    {{ form.as_p }}
    <button name="submit">Save changes</button>
  </form>

{% endblock content %}

index.html:

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

{% block content %}
  <p>Learning Log helps you keep track of what you've learned.</p>
{% endblock content %}

and that is literally everything I checked and I can't seem to find the error, please help me find the error and fix it.

1

There are 1 answers

1
dr_rompecabezas On

In views.py, on the edit_entry function, pass context to the render method.

On the very last line of the edit_entry function, in the views.py file, add the context to the arguments you are passing to the returned render method.

def edit_entry(request, entry_id):
    """Edit and existing entry."""
    entry = Entry.objects.get(id=entry_id)
    topic = entry.topic

    if request.method !='POST':
        form = EntryForm(instance=entry)
    else:
        form = EntryForm(instance=entry, data=request.POST)
        if form.is_valid():
            form.save()
            return redirect('learning_logs:topic', topic_id=topic.id)

   context = {'entry': entry, 'topic': topic, 'form': form}
   return render(request, 'learning_logs/edit_entry.html')

Correct the last line as follows, by adding context. This is so can you can use the entry, topic, and form that you defined in the context in the html template.

   return render(request, 'learning_logs/edit_entry.html', context)