daslashi
daslashi

Reputation: 377

How to add current user data when saving in django model

I am creating small Django/AngularJS app. User can create account, view all created posts and add his own posts.

The current version of app is here: GitHub

Models: models.py

from django.db import models
from django.contrib.auth.models import User

from datetime import datetime

# Post model
class Post(models.Model):
    date = models.DateTimeField(default=datetime.now)
    text = models.CharField(max_length=250)
    author = models.ForeignKey(User)

Views: views.py

from django.shortcuts import render
from rest_framework import generics, permissions

from serializers import UserSerializer, PostSerializer
from django.contrib.auth.models import User
from models import Post
from permissions import PostAuthorCanEditPermission

...

class PostMixin(object):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [
        PostAuthorCanEditPermission
    ]

    def pre_save(self, obj):
        """Force author to the current user on save"""
        obj.author = self.request.user
        return super(PostMixin, self).pre_save(obj)


class PostList(PostMixin, generics.ListCreateAPIView):
    pass


class PostDetail(PostMixin, generics.RetrieveUpdateDestroyAPIView):
    pass

...

Serializers: serializers.py

from rest_framework import serializers
from django.contrib.auth.models import User
from models import Post


class UserSerializer(serializers.ModelSerializer):
    posts = serializers.HyperlinkedIdentityField(view_name='userpost-list', lookup_field='username')

    class Meta:
        model = User
        fields = ('id', 'username', 'first_name', 'last_name', 'posts', )


class PostSerializer(serializers.ModelSerializer):
    author = UserSerializer(required=False)

    def get_validation_exclusions(self, *args, **kwargs):
        # Need to exclude `user` since we'll add that later based off the request
        exclusions = super(PostSerializer, self).get_validation_exclusions(*args, **kwargs)
        return exclusions + ['author']

    class Meta:
        model = Post

But when I create request (main.js) to add new post to DB like this:

var formPostData = {text: $scope.post_text};
$http({
  method: 'POST',
  url: '/api/posts',
  data: formPostData,
  headers: {'Content-Type': 'application/json'}
})

it raises error:

Request Method: POST
Request URL:    http://127.0.0.1:8000/api/posts
Django Version: 1.7.6
Exception Type: IntegrityError
Exception Value:    
NOT NULL constraint failed: nucleo_post.author_id

I thought, that this code adds author to the post model before saving. But it doesn't work correctly now.

def pre_save(self, obj):
    """Force author to the current user on save"""
    obj.author = self.request.user
    return super(PostMixin, self).pre_save(obj)

So I need some help...

Upvotes: 1

Views: 926

Answers (1)

Ishan Anand
Ishan Anand

Reputation: 403

this is because the request does not have the user information. For request.user to work, the request should include the authorization related information. Inclusion of this information depends on what authorization mechanism you are using. If you are using token or session based authentication then token or session key should be the part of request header or query param(depends on server implementation). If you are using rest_framework's login view then you should pass username:password along with the request.

Upvotes: 1

Related Questions