Rony Ahmmod
Rony Ahmmod

Reputation: 59

Django IntegrityError: NOT NULL constraint failed

I want to create model Serializers and all the necessary code. I want to solve a Coursera project assesment of API course.

Error: django.db.utils.IntegrityError: NOT NULL constraint failed: LittleLemonAPI_menuitem.category_id

That occurs when I define depth = 1 in MenuItemSerializer and create a new menu item. If I remove depth = 1 and category = CategorySerializer there is no error. But then table Category is not populated.

serializers.py

from rest_framework import serializers, validators
from .models import Category, MenuItem, Cart, Order, OrderItem
from django.contrib.auth.models import User, Group, Permission

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ['id', 'slug', 'title']

        validators = [
            validators.UniqueTogetherValidator(
                queryset=Category.objects.all(),
                fields=('title',),
                message="Category must be unique"
            )
        ]

class MenuItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = MenuItem
        category = CategorySerializer()
        fields = ['id', 'title', 'price',
                  'featured', 'inventory', 'category',]
        depth = 1

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'groups',]
        depth = 1

class CartSerializer(serializers.ModelSerializer):
    class Meta:
        model = Cart
        user = UserSerializer()
        menuitem = MenuItemSerializer()
        fields = ['id', 'user', 'menuitem', 'quantity', 'unit_price', 'price']
        depth = 1
        validators = [
            validators.UniqueTogetherValidator(
                queryset=MenuItem.objects.all(),
                fields=('id',),
                message="Menuitem should be unique in this curt"
            ),
            validators.UniqueTogetherValidator(
                queryset=User.objects.all(), fields=('id'), message="User should be unique")
        ]

class OrderSerilizer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = ['id', 'user', 'delivery_crew', 'status', 'total', 'date']
        depth = 1

class OrderItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderItem
        fields = ['id', 'order', 'menuitem', 'quantity', 'unit_price', 'price']
        depth = 1
        validators = [
            validators.UniqueTogetherValidator(
                queryset=Order.objects.all(),
                fields=('id',)
            ),
            validators.UniqueTogetherValidator(
                queryset=MenuItem.objects.all(),
                fields=('id',)
            )
        ]

models.py

from django.db import models
from django.contrib.auth.models import User
# Create your models here.

class Category(models.Model):
    slug = models.SlugField()
    title = models.CharField(max_length=255, db_index=True)

class MenuItem(models.Model):
    title = models.CharField(max_length=255, db_index=True)
    price = models.DecimalField(max_digits=6, decimal_places=2, db_index=True)
    featured = models.BooleanField(db_index=True)
    category = models.ForeignKey(Category, on_delete=models.PROTECT)
    inventory = models.IntegerField()

class Cart(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    menuitem = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
    quantity = models.SmallIntegerField(),
    unit_price = models.DecimalField(max_digits=6, decimal_places=2)
    price = models.DecimalField(max_digits=6, decimal_places=2)

    class Meta:
        unique_together = ('menuitem', 'user')

class Order(models.Model):
    user = models.ForeignKey(User, models.CASCADE)
    delivery_crew = models.ForeignKey(
        User, on_delete=models.SET_NULL, related_name='delivery_crew', null=True)
    status = models.BooleanField(db_index=True, default=0)
    total = models.DecimalField(max_digits=6, decimal_places=2)
    date = models.DateField(db_index=True)

class OrderItem(models.Model):
    order = models.ForeignKey(User, on_delete=models.CASCADE)
    menuitem = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
    quantity = models.SmallIntegerField()
    unit_price = models.DecimalField(max_digits=6, decimal_places=2)
    price = models.DecimalField(max_digits=6, decimal_places=2)

    class Meta:
        unique_together = ('order', 'menuitem')

Upvotes: 0

Views: 48

Answers (1)

alan
alan

Reputation: 148

Error: django.db.utils.IntegrityError: NOT NULL constraint failed: LittleLemonAPI_menuitem.category_id

This error is telling you that you have to provide a category id when you create a menu item.

And the other error is using depth in a write serializer. Removing that and the category in the Meta you should be fine.

With this serializer:

class MenuItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = MenuItem
        fields = ['id', 'title', 'price',
                  'featured', 'inventory', 'category',]

Then you just have to pass a dictionary with all these fields: title, price, featured, inventory and a valid category id.

Upvotes: 0

Related Questions