Chapter 14. Managing Site Users

<feature><title>What You’ll Learn in This Hour</title> <objective>

How to create User objects in your views

</objective>
<objective>

How to add Group objects to the website and assign them to users

</objective>
<objective>

How to create custom permissions in the model

</objective>
<objective>

How to assign permissions to users and groups

</objective>
</feature>

So far in this book, we have neglected one of the most basic parts of most websites—registration and authentication. Django includes several components that aid in registration and authentication.

This hour discusses getting started with the registration and authentication process. We will cover creating User and Group objects as well as adding custom permissions to your models. We will also discuss setting permissions that allow you to control access to parts of the website.

By the Way

Django currently provides a whole series of manipulator objects and built-in views to handle user creation, logins, logouts, password changes, and so on. Those manipulators are currently based on the old form framework, so I avoid using them. The examples that I will discuss cover creating your own Forms using the newforms library. I also will show you how to customize the registration and login process.

Adding Users

The first step in adding registration and authentication to the website is to implement some kind of User object so that you can determine who is trying to access the site. Hour 3, “Adding Models and Objects to Your Website,” introduced the admin interface and showed you how to use it to create User objects. Django implements User objects in the admin interface to control access. User objects can also be accessed from your views as part of registration, authentication, and permission control.

The following sections discuss User objects and how to create them from a view function.

Understanding User Objects

Django User objects give you a way to control access to your website by providing a means to force requests to come from authenticated sources. Implementing User objects also allows you to define permissions to specific areas of the website.

The following list describes the fields of a User object:

  • username is required. It accepts up to 30 alphanumeric and underscore characters.

  • first_name is optional. It accepts up to 30 characters.

  • last_name is optional. It accepts up to 30 characters.

  • email is optional. It accepts a valid email address.

  • password is required. The password is actually stored as a hash that describes the raw password.

  • is_staff is Boolean. It defaults to False. It specifies whether the user can access the admin site.

  • is_active is Boolean. It defaults to True. It specifies whether the user can log into the website.

  • is_superuser is Boolean. It defaults to False. It specifies whether the user has all permissions to the admin site.

  • last_login is a datetime object containing the time when the user last logged in.

  • date_joined is a datetime object containing the time when the User object was created.

  • groups is a many-to-many field that lists Group objects that the User belongs to.

  • user_permissions is a many-to-many field that lists permissions assigned to the User.

Anonymous Users

Django implements a special User class to handle anonymous requests. If a request comes from a user who is not currently logged in, the user attribute of the HttpRequest object is a django.contrib.auth.model.AnonymousUser object. The AnonymousUser object is like a normal User object, with the following exceptions:

  • id is always None.

  • is_staff is always False.

  • is_superuser is always False.

  • is_active is always True.

  • groups and user_permissions are always empty.

  • is_anonymous() returns True instead of False.

  • has_perm() always returns False.

  • The set_password(), check_password(), save(), delete(), set_groups(), and set_permission() functions raise a NotImplementedError.

Creating User Objects in Views

The admin interface is an excellent way to create objects. However, you will likely want to automate the creation of User objects by providing a web page that allows people to register with your website. When new users register, they will be able to create their own User objects and immediately access the website using their new account.

You can create User objects from the view function by calling the User.objects create_user(username, email, password=None) function and passing it username, email, and password as arguments.

For example, the following code creates a new User object for a user named Tim:

from django.contrib.auth.models import User
user = User.objects.create_user('Tim', '[email protected]', 'timspass')

Watch Out!

Not specifying a password when using the create_user() function is not the same as entering a blank string for the password. An unuseable password is added, and the User object function has_useable_password() returns True. This feature can actually be useful if you are importing User objects from some other source using an automated method and you do not want to give them all the same generic password.

Changing User Passwords in Views

You can change user passwords in the Django admin interface. However, you may also want to allow users to change their own passwords. To do so, you can create a view that renders a password change form similar to that of a login form. Then, inside the view, use the User.set_password() function on the User object of the request to change the password of the currently logged-in user.

The following code snippet shows the POST handler from a password change view function that sets the password of the current User object:

if request.method == 'POST':
    if request.POST['submit'] == 'Change Password':
        newPass = request.POST['password']
        request.user.set_password(newPass)
        request.user.save()
        return HttpResponseRedirect('/home')

Adding Groups

Django provides a django.contrib.auth.models.Group object that can be added to the groups field of a User object. The Group object has two fields—name and permissions. When you set the permissions attribute of the Group object, the permissions flow to each User who is a member of the group.

You can create a Group object using the following code:

from django.contrib.auth.models import Group
newGroup = Group()
newGroup.name = 'New Group'
newGroup.save()

Group objects can be added to and removed from a User object using the add(), remove(), and clear() functions. The add() and remove() functions accept one or more groups and then either add them to or remove them from the User object. The clear() function removes all the groups from the User object. The following code shows an example of the add(), remove(), and clear() functions:

user.groups.add(groupA, groupB)
user.groups.remove(groupC, groupD)
user.groups.clear()

Group objects can also be assigned to User objects in the admin interface. The User object details page lists groups that exist in the site. If you select groups in the groups list, the Group objects are added to the User.

The Group objects that belong to a user can be accessed through the groups attribute of the User object, as shown in the following line of code:

userGroups = user.groups

Group objects are the best way to assign permissions to several users at the same time. They are also a great way to collect users under a single label.

Setting User Permissions

In Django, permissions are basically just a way to set flags for users and groups that either allow or inhibit them from performing certain actions. Permissions are created at the model object level and can be assigned to either a User or Group object.

Did you Know?

Permissions are set globally per object type. You cannot create permission to control a specific instance of the object. For example, you cannot add a permission that would apply only to objects that a specific user creates.

You will work with two different types of permissions. The first type is basic permissions that get assigned to objects automatically. The second type is custom permissions that you create yourself. The following sections discuss the different types of permissions.

Basic Permissions

Three types of basic permissions are automatically added to each model. The create, add, and delete permissions are added to the auth_permission table in the database for each model. These permissions limit access to the add, change, and delete forms for the model in the admin interface.

Watch Out!

The basic permissions are added for the model only if you include the class admin definition in the model. If you didn’t initially add the class admin definition in the model, you need to add it and then run the syncdb utility to add the permissions.

By the Way

Although basic permissions are designed for the admin interface, you can access and use them in your views to verify permissions for users. This is discussed more in the next hour.

Creating Custom Permissions

You create custom permissions in the model by adding them to the permissions attribute of the Meta class. To assign permissions, add them as a two-element list. The first element is the permission identifier, and the second is a textual name for the permission.

For example, the following code adds the custom permissions can_read and can_write to the Student model:

class Student(models.Model):
    . . .
    class Meta:
        permissions = (
            ('can_read', 'Reads Well'),
            ('can_write', 'Writes Well'),
        )

Watch Out!

After you add the permissions to the Meta class in the model, you need to run the syncdb utility to add the permissions to the database.

Adding Permissions to Users and Groups

You can add permissions to User and Group objects in one of two ways—by using Python code in your views or by using the admin interface.

Permissions objects can also be assigned to User or Group objects in the admin interface. The User and Group object details page lists available user permissions that exist in the site. If you add permissions in the available permissions list to the chosen permissions list, the permissions are available to the user or group.

You can add or remove permissions to and from a User or Group object using the add(), remove(), and clear() functions. The add() and remove() functions accept one or more permissions and then either add them to or remove them from the User or Group object. The clear() function removes all permissions from the User object.

The following code shows an example of the add(), remove(), and clear() functions on a User object:

userOBJ.user_permissions.add(permissionA, permissionB)
userOBJ.user_permissions.remove(permissionC, permissionD)
userOBJ.user_permissions.clear()

The following code shows an example of the add(), remove(), and clear() functions on a Group object:

groupOBJ.permissions.add(permissionA, permissionB)
groupOBJ.permissions.remove(permissionC, permissionD)
groupOBJ.permissions.clear()

Example 14.3. Blog Model Definition in the iFriends/People/models.py File

class Blog(models.Model):
    title = models.CharField('Title', max_length=200)
    text = models.TextField('Text', max_length=2048)
    date = models.DateTimeField('Last Modified')

    def __str__(self):
        return '%s' % (self.title)

    class Admin:
        pass

    class Meta:
        permissions = (
            ('can_blog', 'Allowed to Blog'),
        )

Summary

In this hour, we discussed User objects and how to create them using custom forms in a view. We also discussed how to create Group objects. You can assign Group objects to User objects either from the admin interface or from your views. As soon as you have User and Group objects in place, you can add custom permissions to your models and assign them to User and Group objects.

Q&A

Q.

Is there a way to create a Django superuser object without accessing the admin interface or creating a new database?

A.

Yes. A create_superuser.py application is located in the following location relative to where you installed Django:

django/contrib/auth/create_superuser.py

It prompts you for a superuser name and password.

Q.

Is there a way to quickly email the user to let her know that her account has been created?

A.

Yes. The User object includes the function email_user(subject, message, from_email=None). After the User object has been created, call the email_user() function with the subject, message, and from address (optional). The user will be notified at the email address she specified when registering the account.

Workshop

The workshop consists of a set of questions and answers designed to solidify your understanding of the material covered in this hour. Try answering the questions before looking at the answers.

Quiz

1.

What function can you use to create User objects from a view function?

2.

Where do you add custom permission objects?

3.

In what format are passwords stored in the database?

4.

How do you verify textual passwords against passwords in the database?

Quiz Answers

1.

The User.objects.create_user() function.

2.

Custom permissions are added to the Meta attribute of objects in the model.

3.

Passwords are stored as a hash inside the database in the format hashtype$salt$hash.

4.

You use the User.check_password(textual_password, db_password) function.

Exercises

1.

Create some additional People objects and an additional group, Friendly, in the database.

2.

Add some of the users in the database to the Friendly group.

3.

Create a custom permission in the Person class called can_add_friends.

4.

Add the can_add_friends custom permission to the Friendly group.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.107.181