2

I want to get the current logged in user to this CreateForm form. Below Im giving my current code, here request.user is not giving me error

ValueError at /create-post/ Cannot assign "<SimpleLazyObject: <User: testuser>>": "Post.author" must be a "Author" instance.

models.py

class Author(models.Model):
   user = models.OneToOneField(User, on_delete=models.CASCADE)
   rate = models.IntegerField(default=0)
 
class Post(models.Model):
    title = models.CharField(max_length= 50)
    overview = models.TextField()
    body_text = RichTextUploadingField(null = True)
    time_upload = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(Author, related_name='author', on_delete=models.CASCADE)
    thumbnail = models.ImageField(upload_to = 'thumbnails')
    publish = models.BooleanField()
    categories = models.ManyToManyField(Categories)
    read = models.IntegerField(default=0)
    slug = models.SlugField(null= True, blank= True)

Forms.py

class CreateForm(ModelForm):
class Meta:
    model = Post
    fields = [
        'title',
        'overview',
        'body_text',
        'thumbnail',
        'categories',
        'publish',
    ]

Views.py

def create_post(request):
if request.method == 'POST':
    form = CreateForm(request.POST, request.FILES)
    if form.is_valid:
        post = form.save(commit=False)
        post.author= request.user
        post.save()
        return render(request, 'index.html')
else:
    form = CreateForm()
return render(request, 'create_post.html', {'form': form})
Manas S. Roy
  • 303
  • 1
  • 10

2 Answers2

2

As the error says, post.author expects an Author object, not the user. You thus retrieve this with:

from django.contrib.auth.decorators import login_required

@login_required
def create_post(request):
    if request.method == 'POST':
        form = CreateForm(request.POST, request.FILES)
        if form.is_valid():
            form.instance.author= request.user.author
            form.save()
            return render(request, 'index.html')
    else:
        form = CreateForm()
    return render(request, 'create_post.html', {'form': form})

You should also call the is_valid() method [Django-doc], so form.is_valid().


Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
2

The author field on your Post model is a foreign key to Author model, and not user. You could replace post.author = request.user with:

if request.user.author:
    post.author = request.user.author
else:
    post.author = Author.objects.create(user=request.user)

The answer from Willem works if an Author instance was already created for the User, but will throw an exception if there's no Author object associated with that user.

  • Thank you. I just want get the current logged in user only, I don't want to create a new one. As I will modify this one with login decorators. – Manas S. Roy Apr 05 '22 at 10:52
  • This snippet is not for creating a new user, it's for creating an author object to associate with that user in case it was not created before – Kauê Oliveira Apr 05 '22 at 10:54
  • @KauêOliveira: this will likely not work since `request.user.author` will raise an `AttributeError` (`RelatedObjectDoesNotExists`) when there is no related `Author` object. – Willem Van Onsem Apr 05 '22 at 11:07
  • It won't. It would raise `AttributeError` if we tried to access any attributes on the author, for example `request.user.author.rate`, which is not the case. – Kauê Oliveira Apr 05 '22 at 11:19
  • 2
    @KauêOliveira: notice that the `OneToOneField` is *reversed*: hence it will *not* return `None`. There has been a lot of dicussion about this, but `.author` will *not* return `None`. See https://code.djangoproject.com/ticket/3016 and https://stackoverflow.com/questions/33610563/django-onetoone-reverse-relation-doesnotexists-when-empty – Willem Van Onsem Apr 05 '22 at 11:24