Python Django Authentication Users and Authorization Custom Permission

Nathan Magyar
Nathan Magyar
11,332 Points

Django Custom Permission

In an app called Products, I have created a custom permission called 'can_give_discount' on the Product model and now I need to override the form_valid method for the respective Create view. If the user (self.request.user) does not have the right permission (check with has_perm), I should set the saved object's (self.object) discount to 0. I should also resave the object.

The error I'm currently receiving is that a user without the 'can_give_discount' permission was able to provide a discount.

products/models.py
from django.core.urlresolvers import reverse
from django.db import models


class Product(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    price = models.DecimalField()
    discount = models.DecimalField(blank=True, null=True)

    class Meta:
        permissions = (
            ('can_give_discount', 'Can give a discount'),
        )

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("products:detail", kwargs={"pk": self.pk})
products/views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import generic

from . import models


class List(generic.ListView):
    model = models.Product


class Detail(generic.DetailView):
    model = models.Product


class Create(LoginRequiredMixin, generic.CreateView):
    fields = ("name", "description", "discount", "price")
    model = models.Product

    def form_valid(self, form):
        if not self.request.user.has_perm("products.can_give_discount"):
            self.object.discount = 0
        self.object.save()

1 Answer

Michael ‍
Michael ‍
Python Web Development Techdegree Graduate 14,109 Points
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import generic

from . import models


class List(generic.ListView):
    model = models.Product


class Detail(generic.DetailView):
    model = models.Product


class Create(LoginRequiredMixin, generic.CreateView):
    fields = ("name", "description", "discount", "price")
    model = models.Product

    def form_valid(self, form):
        if not self.request.user.has_perm("products.can_give_discount"):
            obj = form.save(commit=False)
            obj.discount = 0
            obj.save()
        return super(Create, self).form_valid(form)