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 Django Authentication Users and Authorization Add to Group

Chris Komaroff
PLUS
Chris Komaroff
Courses Plus Student 14,198 Points

Django user creation, permission group, challenge task fails.

I wish there was a specific question I could ask, but the error message "Bummer! Try Again!" does not give me very much to go on. Not sure what is wrong. Am not sure if we need to check if the group 'editors' has a permission and add it if not - use group.permissions.set()? Is there a syntax error?

accounts/models.py
from django.contrib.auth.models import (
    PermissionsMixin,
    BaseUserManager,
    AbstractBaseUser,
    Permission,
    Group
)
from django.db import models
from django.utils import timezone


class UserManager(BaseUserManager):
    def create_user(self, email, dob, accepted_tos=None, password=None):
        if not accepted_tos:
            raise ValueError("Users must accept the terms of service")

        user = self.model(
            email=self.normalize_email(email),
            dob=dob,
            accepted_tos=True
        )
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, dob, password):
        user = self.create_user(
            email,
            dob,
            accepted_tos=True,
            password=password
        )
        user.is_staff = True
        user.is_superuser = True
        user.save()
        return user

    def create_editor(self, email, dob, password):
        user = self.create_user(
            email,
            dob,
            accepted_tos=True,
            password=password
        )
        try:
            editors = Group.objects.get(name__iexact="editors")
        except Group.DoesNotExist:
            editors = Group.objects.create(name="Editors")
        if not editors.permissions.set(["accounts.can_give_discount"]):
            editors.permissions.add(
                Permission.objects.get(codename="can_give_discount")
            editors.save()
        user.groups.add(editors)                        
        return user


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    dob = models.DateField()
    accepted_tos = models.BooleanField()
    is_staff = models.BooleanField(default=False)
    joined_at = models.DateTimeField(default=timezone.now)

    objects = UserManager()

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = ["dob"]

1 Answer

William Li
PLUS
William Li
Courses Plus Student 26,868 Points

Hi Chris, I was asked to answer this question, so let me help you out here.

I can see that you're definitely on the right track to solving this challenge, and it shows in your code. Here're some of the things need to be corrected to pass the grader.

  • the if conditional check really isn't needed here.
  • user.groups.add(editors) is there, but the user.save() line is missing. Since these two line should be executed unconditionally whether or not an except was caught, we should put 'em outside of the try...except clauses, and right before the return user line.
    def create_editor(self, email, dob, password):
        user = self.create_user(
            email,
            dob,
            accepted_tos=True,
            password=password
        )

        try:
            editors = Group.objects.get(name__iexact="Editors")
        except Group.DoesNotExist:
            editors = Group.objects.create(name="Editors")

        editors.permissions.add(Permission.objects.get(codename="can_give_discount")) # add can_give_discount permission
        user.groups.add(editors)
        user.save()
        return user

Hope it helps, feel free to tag me if there's further question. cheers.

Chris Komaroff
Chris Komaroff
Courses Plus Student 14,198 Points

Thank you! I was thinking maybe group.permissions.add() would not add the same permission twice if it already exists, but could not find the info in djangoprojects / docs. So I thought I had to test. But my missing 'user.save()' is funny! Always save your model instance to db.

Luis Onate
Luis Onate
13,222 Points

I tried my code using the get_or_create method, but was getting an error saying "Superuser couldn't create a discounted product." Should my code work? It's hard to tell, since the message references the superuser, if my code is wrong or if it's an error in checking the code. As I'm thinking through it, my code makes sense to me, but once you get so close to something it's easy to think it's right when it's completely wrong. Could someone offer up a fresh set of eyes? Ended up using the code above to pass the challenge, but I feel like this code, or some variation of it, should work.

def create_editor(self, email, dob, password):
    user = self.create_user(
        email,
        dob,
        accepted_tos=True,
        password=password
    )

    editor_group, editor_group_created = Group.objects.get_or_create(name='Editor')
    discount_permission = Permission.objects.get(codename="can_give_discount")

    editor_group.permissions.add(discount_permission)

    user.groups.add(editor_group)
    user.save()            
    return user
Cristian Romero
Cristian Romero
11,911 Points

this threw me off because in the challenge is done on the models.py in the video example, it is done in the views.py.