Django.fun

Prevent User from creating instance for other users

I have 4 models each related to each other with ForeignKey.

class User(models.Model):
    name = models.CharField()

class Business(models.Model):
    name = models.CharField() //business name
    created_by = models.ForeignKey(User,related_name=businesses,on_del=models.CASCADE)

class ProdCategory(models.Model):
    business = models.ForeignKey(Business,related_name=categories,on_del=models.CASCADE)
    name = models.CharField()

class Product(models.Model):
    category = models.ForeignKey(ProdCategory,related_name=products,on_del=models.CASCADE)
    name = models.ForeignKey()
    price = models.DecimalField()

Now If I try to get all the Products of the current authenticated user I get the Correct List of products (that coming from the same User>Business>ProdCategory>Product)

But if I try to create a Product with authenticated user, I can create a Product with providing the id of ProdCategory(already created by different users) (User of Business>ProdCategory) != self.request.user

In Short I can create product for other users. Which is not what I want. I want to prevent the current user from creating products if ProdCategory id provided is of different users. It should return error. User must provide the id of ProdCategory that was created by the same user.

Serializer classes are defined with all fields using ModelSerializer.

Here goes the View for creating and listing products:

class ProductListCreateView(generics.ListCreateAPIView):
    serializer_class = ProductListCreateSerializer

    def get_queryset(self):
        return Product.objects.filter(category__business__created_by=self.request.user)

I would appreciate any help.

I didn't see your create product side. So I just write the logic.

prodCategory= ProdCategory.objects.get(id=1)
if prodCategory.business.created_by == request.user:
     #let user to create the product
     Product.objects.create()
else:
    return False

I hope you understand the logic

Basically What I wanted is to prevent the user from pushing Product to ProdCategory that is not own by the user.

I just found a solution. so I'm adding this here in case anybody else come across the same issue.

to prevent the user I added a validation for category in Product serializer. Overriding the create method is not necessary.

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'
    
    def validate_category(self, value):
        category_id = value.id
        category = ProdCategory.objects.get(id=category_id)
        user = self.context['request'].user
        if category.business.created_by != user:
            raise serializers.ValidationError("You do not have permission")
        return value

Tutorials

Современный Python: начинаем проект с pyenv и poetry

Настройка проекта Python — виртуальные среды и управление пакетами

Использование requests в Python — тайм-ауты, повторы, хуки

Понимание декораторов в Python

ProcessPoolExecutor в Python: полное руководство

map() против submit() с ProcessPoolExecutor в Python

Понимание атрибутов, словарей и слотов в Python

Полное руководство по slice в Python

Выпуск Django 4.0

Безопасное развертывание приложения Django с помощью Gunicorn, Nginx и HTTPS

Автоматический повтор невыполненных задач Celery

Django REST Framework и Elasticsearch

Докеризация Django с помощью Postgres, Gunicorn и Nginx

Асинхронные задачи с Django и Celery

Релизы безопасности Django: 3.2.4, 3.1.12 и 2.2.24

Выпуски исправлений ошибок Django: 3.2.3, 3.1.11 и 2.2.23

Эффективное использование сериализаторов Django REST Framework

Выпуски безопасности Django: 3.2.2, 3.1.10 и 2.2.22

Выпущенные релизы безопасности Django: 3.2.1, 3.1.9 и 2.2.21

Обработка периодических задач в Django с помощью Celery и Docker

View all tutorials →