DevolamiTech
DevolamiTech

Reputation: 320

IntegrityError in Django Custom User Model which doesn't go away even after deleting all migrations

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:

Custom user Model

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

Answers (2)

Solomon Botchway
Solomon Botchway

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

user21986643
user21986643

Reputation:

could you add Post Model to your data ? maybe I can help if I see it...

Upvotes: 0

Related Questions