Eid Alhamali
Eid Alhamali

Reputation: 5

Editing posts in a Django blog

Note: there's a similar question to mine, there're a few differences in our code, and I tried the solutions to his question, didn't work for me.

I'm working on a blog using Django, I'm trying to add an edit_post feature but when I go to localhost:8000 it shows NoReverseMatch, the problem is related to the post's id, I'm trying to create a home page that shows the post's title and it's content. here'e my code:

models.py

from django.db import models

# Create your models here.

class BlogPost(models.Model):
    title = models.CharField(max_length=20)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

def __str__(self):
    return self.title

urls.py

from django.urls import path

from . import views
app_name = 'blogs'
urlpatterns = [
    # Home page
    path('', views.index, name='index'),
    # page for adding a new post
    path('new_post/', views.new_post, name='new_post'),
    # page for editing a post
    path('edit_post/<int:post_id>/', views.edit_post, name='edit_post'),
]

index.html

{% block content %}

<p>My personal Blog</p>

<a href="{% url 'blogs:new_post' %}">Add a new post</a>

<ul>
    {% for p in posts %} 
    # the problem is probably here
      <li>{{ p.title }}</li>
      <li>{{ p.text }}</li>
        <p>
          <a href="{% url 'blogs:edit_post' post.id %}">Edit post</a>
        </p>

    {% endfor %}
</ul>



{% endblock content %}

edit_post.html

{% block content %}


  <p>Edit post:</p>

  <form action="{% url 'blogs:edit_post' post.id %}" method='post'>
      {% csrf_token %}
      {{ form.as_p }}
      <button name="submet">Save changes</button>
  </form>

{% endblock content %}

new_post.html

{% block content %}
  <P>Add a new post:</P>

  <form action="{% url 'blogs:new_post' %}" method='post'>
      {% csrf_token %}
      {{ form.as_p }}
      <button name="submet">Add post</button>
  </form>

  {% endblock content %}

views.py

from django.shortcuts import render, redirect

from .models import BlogPost

from .forms import BlogPostForm

# Create your views here.

def index(request):
    posts = BlogPost.objects.order_by('date_added')
    context = {'posts': posts}
    return render(request, 'blogs/index.html', context)

def new_post(request):
    """Add a new post."""
    if request.method != 'POST':
        form = BlogPostForm()

    else:
        form = BlogPostForm(data=request.POST)
        if form.is_valid():
            new_p = form.save()
            return redirect('blogs:index')

    context = {'form': form}
    return render(request, 'blogs/new_post.html', context)

def edit_post(request, post_id):
    post = BlogPost.objects.get(id=post_id)

    if request.method != 'POST':
        form = BlogPostForm(instance=post)

    else:
        form = BlogPostForm(instance=post, data=request.POST) 
        if form.is_valid():
            form.save()
            return redirect('blogs:index', post_id=post.id)


    context = {'post': post, 'index': index, 'form': form}
    return render(request, 'blogs/edit_post.html', context)

forms.py

from django import forms

from .models import BlogPost

class BlogPostForm(forms.ModelForm):
    class Meta:
        model = BlogPost
        fields = ['title', 'text']
        labels = {'text': ''}
        widgets = {'text': forms.Textarea(attrs={'cols':80})}

Upvotes: 0

Views: 1752

Answers (1)

dstrants
dstrants

Reputation: 7705

The problem is with the arguments of the url you are creating on index.html, you are looping posts as p in html so try to change:

<a href="{% url 'blogs:edit_post' post.id %}">Edit post</a>

With

<a href="{% url 'blogs:edit_post' p.id %}">Edit post</a>

Upvotes: 1

Related Questions