Reputation: 320
I keep getting this error whenever I tried to create a post. I have gone through all similar questions on this platform and made several adjustments but the error still occurs.
IntegrityError at /api/admin/create/ NOT NULL constraint failed: blog_post.author_id Request Method: POST Request URL: http://127.0.0.1:8000/api/admin/create/
Below is my cusstom user model:
class NewUser(PermissionsMixin, AbstractBaseUser):
email = models.EmailField(_('email_address'), unique=True)
user_name = models.CharField(max_length=150, unique=True)
first_name= models.CharField(max_length=150, blank=True)
about = models.TextField(_('about'), max_length=500, blank=True)
start_date = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=True)
objects = CustomAccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'user_name']
Below is my custom manager for the custome user model:
class CustomAccountManager(BaseUserManager):
def create_superuser(self, email, user_name, first_name, password, **other_fields):
other_fields.setdefault('is_superuser', True)
other_fields.setdefault('is_staff', True)
other_fields.setdefault('is_active', True)
if other_fields.get('is_superuser') is not True:
raise ValueError('superuser must be assigned to is_superuser=True')
if other_fields.get('is_staff') is not True:
raise ValueError('superuser must be assigned to is_staff=True')
user = self.create_user(email, user_name, first_name, password, **other_fields)
user.save(using=self._db)
return user
def create_user(self, email, user_name, first_name, password, **other_fields):
if not email:
raise ValueError(_('You must provide an email address'))
email = self.normalize_email(email)
user = self.model(email=email, user_name=user_name, first_name=first_name, **other_fields)
user.set_password(password)
user.save()
return user
Below is my serializer class for the custome user model:
class RegisterUserSerializer(serializers.ModelSerializer):
email = serializers.EmailField(required=True)
username = serializers.CharField(required=True)
password = serializers.CharField(min_length=8, write_only=True)
class Meta:
model = NewUser
fields = ('email', 'user_name', 'password', 'first_name')
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
password = validated_data.pop('password', None)
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
Below is my view :
class CustomUserCreate(APIView):
permission_classes = [AllowAny]
def post(self, request, format='json'):
reg_serializer = RegisterUserSerializer(data=request.data)
if reg_serializer.is_valid():
newuser = reg_serializer.save()
if newuser:
json = reg_serializer.data
return Response(json, status= status.HTTP_201_CREATED)
return Response(reg_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Here is the post view to which the endpoint "http://127.0.0.1:8000/api/admin/create/" is connected:
class CreatePost(generics.CreateAPIView):
permission_classes = [permissions.IsAuthenticated]
queryset = Post.objects.all()
serializer_class = PostSerializer
First Edit: Here is the Post Model:
class Post(models.Model):
class PostObjects(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(status = 'published')
options = (
('draft', 'Draft'),
('published', 'Published')
)
post_id = models.BigAutoField(primary_key=True)
category = models.ForeignKey(Category, on_delete=models.PROTECT, default=1, related_name="postcategory")
title = models.CharField(max_length=250)
excerpt = models.TextField(null=True)
photo = models.ImageField(_("image"), upload_to=upload_to, default='posts/default.jpg')
content = models.TextField()
slug = models.SlugField(max_length=250, unique_for_date='published')
published = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="blog_posts")
status = models.CharField(max_length=10, choices=options, default='published')
objects = models.Manager() #default manager
postobjects = PostObjects() #custom manager
class Meta:
ordering = ('-published',)
def __str__(self):
return self.title
Second Edit: here is what I have in the settings file:
AUTH_USER_MODEL = "users.NewUser"
THIRD EDIT: This is the View and Serializer I'm using to create Posts:
View
class CreatePost(generics.CreateAPIView):
permission_classes = [permissions.IsAuthenticated]
queryset = Post.objects.all()
serializer_class = PostSerializer
Serializer:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ('post_id', 'category', 'title', 'author', 'content', 'excerpt', 'slug', 'status', 'photo')
Upvotes: 0
Views: 78
Reputation: 789
The Post model needs a user as an author, but no author is being passed. This results in a "NOT NULL constraint failed: blog_post.author_id" error because the author_id cannot be null. To resolve this, please provide the View and Serializer you are using to create Posts. This will allow me to demonstrate how to assign the current user or the user making the request as the author, assuming that is your intention.
EDIT:
Overwrite the create method of your serializer to set the author to the request user:
from rest_framework import serializers
class PostSerializer(serializers.ModelSerializer):
def create(self, validated_data):
validated_data['author'] = self.context['request'].user
return super().create(validated_data)
class Meta:
model = Post
fields = ('post_id', 'category', 'title', 'author', 'content', 'excerpt', 'slug', 'status', 'photo')
Upvotes: 1
Reputation:
could you add Post Model to your data ? maybe I can help if I see it...
Upvotes: 0