Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Can't figure out why I don't pass this task. Custom Permission Challenge Task 2 of 2

Now override the form_valid method for the Create view. If the user (self.request.user) does not have the right permission (check with has_perm), set the saved object's (self.object) discount to 0. Be sure to resave the object!

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()
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", "User can give a sale discount"),
        )

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("products:detail", kwargs={"pk": self.pk})

4 Answers

Jonathan Wadsworth
Jonathan Wadsworth
20,196 Points

You have a formatting issue in your form_valid method: wrong indentation on if clause. You also need to save the form to a variable to allow editing and resaving:

object = form.save(commit=False)
object.discount = 0
object.save()

You may also need to return the form object's super method

return super(Create, self).form_valid(form)
Jianan Li
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Jianan Li
Python Web Development Techdegree Graduate 27,747 Points

The above answer passes the test. However, I think the correct way of doing this is:

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

Inside super().form_valid(form), the model instance is created and passed to self.object. To avoid repeating saving the instance, we should call this super's method first and modify the instance after.

Thanks for your help :) But still have the same issue:

Bummer! A user with the right permission couldn't create a discounted product

def form_valid(self, form):
        if not self.request.user.has_perm("products.can_give_discount"):
            object = form.save(commit=False)
            object.discount = 0
            object.save()
            return super().form_valid(form)
Yasser Arenas
Yasser Arenas
5,879 Points

You're function is only returning the form if the user has not permissions. Moving that return statement outside the if perhaps?

Thanks, Yasser Arenas :)))