TransWikia.com

get_absolute_url() missing 1 required positional argument: 'self'

Stack Overflow Asked on December 2, 2021

I imagine the solution to this can be found i similar topics, however, it seems a little bit different from problems I have seen.

The redirect, in add_post view, should send me to the Post class, where I have a get_absolute_url.

But it happens that I get the following error message: get_absolute_url() missing 1 required positional argument: 'self'

I literally copied the coded form the "Django Projects Cookbook" in case you wanna check it out and try the code yourself.

Thank you.

from django.contrib.auth.decorators import user_passes_test
from django.shortcuts import redirect, render_to_response, get_object_or_404, render

from .models import Post
from .forms import PostForm, CommentForm

@user_passes_test(lambda u: u.is_superuser)
def add_post(request):
    form = PostForm(request.POST or None)
    if form.is_valid():
        post = form.save(commit=False)
        post.author = request.user
        post.save()
        return redirect(Post) # redirect to Post class
    return render(request, 'blog/add_post.html',{ 'form': form })

def view_post(request, slug):
    post = get_object_or_404(Post, slug=slug)
    form = CommentForm(request.POST or None)
    if form.is_valid():
        comment = form.save(commit=False)
        comment.post = post
        comment.save()
        return redirect(request.path)
    return render(request, 'blog/blog_post.html',{'post': post,'form': form,})
from django.db import models
from django.template.defaultfilters import slugify

from django.contrib.auth.models import User

class Post(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    text = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __unicode__(self):
        return self.title

    @models.permalink
    def get_absolute_url(self): # get_absolute_url 
        return ('blog_post_detail', (), { 'slug' :self.slug, })

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

class Comment(models.Model):
    name = models.CharField(max_length=42)
    email = models.EmailField(max_length=75)
    website = models.URLField(max_length=200, null=True, blank=True)
    text = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return self.text

One Answer

You use the Post class, not its object to redirect. You thus need to use post in:

@user_passes_test(lambda u: u.is_superuser)
def add_post(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            form.instance.author = request.user
            post = form.save()
            return redirect(post)
    return render(request, 'blog/add_post.html',{ 'form': form })

The @permalink decorator was removed in Django-2.1, it is advised to use reverse [Django-doc] instead:

from django.urls import reverse

class Post(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    text = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

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

Furthermore is no longer supported since January 1, 2020; so you might want to update to in a environment.

Answered by Willem Van Onsem on December 2, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP