-1

I want the user to be able to update existing posts. When the user clicks Update, then Post, they get an error message saying there is no URL to direct to. But the post does get updated on the backend.

enter image description here

enter image description here

enter image description here

I thought the line return reverse('article_detail', kwargs={'slug': self.slug}) would redirect them back to their original post.

class Post(models.Model):
    title = models.CharField(max_length=100)
    content =  models.TextField()
    date_posted = models.DateTimeField(default=timezone.now())
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    url= models.SlugField(max_length=500, blank=True)
    #url= models.SlugField(max_length=500, unique=True, blank=True)

    def save(self, *args, **kwargs):
        self.url= slugify(self.title)
        super().save(*args, **kwargs)

    def __str__(self):
        return self.title 

    def get_absolute_url(self):
        return reverse('article_detail', kwargs={'slug': self.slug})

Here is the table schema.

sqlite> .schema blog_post
CREATE TABLE IF NOT EXISTS "blog_post" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(100) NOT NULL, "content" text NOT NULL, "url" varchar(500) NOT NULL, "author_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "date_posted" datetime NOT NULL);
CREATE INDEX "blog_post_url_5af1045a" ON "blog_post" ("url");
CREATE INDEX "blog_post_author_id_dd7a8485" ON "blog_post" ("author_id");
sqlite>

views.py

class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Post
    fields = ['title', 'content']

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)


    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            return True
        return False

urls.py

urlpatterns = [
    path('', PostListView.as_view(), name='blog-home'),
    path('post/<int:pk>/', views.post_detail, name='post-detail'),
    path('post/new/', PostCreateView.as_view(), name='post-create'),
    path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
    path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
    path('about/', views.about, name='blog-about'),
    path('facebook/',TemplateView.as_view(template_name='blog/index.html'), name="facebook")
]

Update

I use to have self.url= slugify(self.title) and I changed to self.url= slugify(self.id). Because to access my posts, you put in the ID number and not title. Unfortunately the problem persisted.

class Post(models.Model):
    title = models.CharField(max_length=100)
    content =  models.TextField()
    date_posted = models.DateTimeField(default=timezone.now())
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    url= models.SlugField(max_length=500, blank=True)
    #url= models.SlugField(max_length=500, unique=True, blank=True)

    def save(self, *args, **kwargs):
        self.url= slugify(self.id)
        super().save(*args, **kwargs)

enter image description here

Update 2

I am now getting this error message.

Reverse for 'article_detail' not found. 'article_detail' is not a valid view function or pattern name.

enter image description here

Ross Symonds
  • 690
  • 1
  • 8
  • 29

1 Answers1

1

Fix get_absolute_url.

def get_absolute_url(self):
    return reverse('post-detail', kwargs={'pk': self.pk})
Andy
  • 654
  • 7
  • 17