Chinaunix首页 | 论坛 | 博客
  • 博客访问: 71453
  • 博文数量: 23
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 270
  • 用 户 组: 普通用户
  • 注册时间: 2014-12-05 21:57
文章分类
文章存档

2016年(4)

2015年(5)

2014年(14)

我的朋友

分类: Web开发

2015-04-30 16:17:08

 

在这个部分,我们将要开始学习如何设计用户系统,Django提供了一个叫“django.contrib.auth”的应用,我们可以用它来做出用户注册、登录、注销等一系列功能。

17.用户模型


在Django自带的用户系统中,用户模型里已经包含了如下数据:

  • 用户名
  • 密码
  • 电子邮箱
  • 姓名

我们想在用户模型中增加一些额外的字段,如:

  • 链接字段:允许用户展示他们自己的个人网站
  • 图片字段:让用户可以给自己设置一个头像

我们只要更新模型就可以实现上述的需求,编辑rango/models.py文件,先在头部加入一行:

rango/models.py:

from django.contrib.auth.models import User
然后在文件尾部加入如下内容:

rango/models.py:

class UserProfile(models.Model):
    # 这一句是必须的,链接UserProfile到Django的用户模型
    user = models.OneToOneField(User)

    # 我们想要增加的额外字段
    website = models.URLField(blank=True)
    picture = models.ImageField(upload_to='profile_images', blank=True)

    # 重写__str__方法,让它在被调用时显示用户名
    def __str__(self):
        return self.user.username

在这两个字段中,我们设置了“blank=True”,正如字面意思显示,这是允许该字段为空的节奏。

注意在“ImageField”字段中有一个“upload_to”属性,它指定了储存用户头像的文件夹,这个叫“profile_images”的文件夹将放在settings.py中指定的MEDIA_ROOT文件夹下,换句话说,它的路径将是:

rangoproject/media/profile_images/

模型做好后,我们需要更新一下数据库,然后在dos命令提示符下运行如下命令:

$ python manage.py makemigrations rango

继续在dos命令提示符下运行命令:

$ python manage.py migrate

 

18.安装PIL

Django的ImageField使用Python的图像库PIL,如果你没有安装PIL,那么需要先安装它。

在Windows平台的Python 3.2环境下,舍得推荐安装这个版本:

找到其中的 () ,下载下来之后,直接安装就可以了。注意,这是适用于Python 32位的版本。

 

19.在管理界面注册UserProfile

编辑rango/admin.py 文件,让它变成下面这个样子:

rango/admin.py

from django.contrib import admin
from rango.models import Category, Page
from rango.models import UserProfile

class PageAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'url')

class CategoryAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug':('name',)}

admin.site.register(Category, CategoryAdmin)
admin.site.register(Page, PageAdmin)
admin.site.register(UserProfile)

 

20.创建用户注册视图和模板

“用户注册”功能将允许用户在我们的网站上创建账号,我们需要为这个功能添加视图和相应的模板。下面是要完成的工作:

  • 创建UserForm和UserProfileForm两个表单;
  • 添加视图,负责处理新建用户;
  • 创建模板,用来显示UserForm和UserProfileForm这俩表单;
  • 将URL映射到上面创建的视图;
  • 在首页中加入注册页面的链接;

让我们一步步来实现这些内容吧!编辑rango/forms.py 文件,让它变成下面这个样子:

rango/forms.py

class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = User
        fields = ('username', 'email', 'password')

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('website', 'picture')

 

你会发现我们在UserForm和UserProfileForm这俩表单中加入了两个Meta类,每个Meta类都带有一个model字段,它会告诉程序这个表单将要关联到数据库中的哪个表,比如UserForm关联到的是User表。

最后,别忘了将forms.py头部改成下面这样:

rango/forms.py

from django import forms
from django.contrib.auth.models import User
from rango.models import Category, Page, UserProfile

搞完上面这些,让我们来创建用户注册视图。

编辑rango/views.py,添加以下内容:

rango/views.py(注意将第一行代码放到文件头部)

from rango.forms import UserForm, UserProfileForm

def register(request):

    # registered:注册成功与否的信号.
    # 先默认为False,等注册成功后程序会将其改为True
    registered = False

    # 如果是一个HTTP POST请求, 就意味着将要处理表单数据.
    if request.method == 'POST':
        # 尝试从提交的信息中获取数据。
        # 注意UserForm和UserProfileForm都会用到这些数据.
        user_form = UserForm(data=request.POST)
        profile_form = UserProfileForm(data=request.POST)

        # 如果表单有效...
        if user_form.is_valid() and profile_form.is_valid():
            # 将用户表单数据储存到数据库.
            user = user_form.save()

            # 用set_password方法处理密码.
            # 然后储存用户数据.
            user.set_password(user.password)
            user.save()

            # 现在来处理UserProfile表单.
            # 先设置commit为False.
            # 这个信号用来延迟数据储存动作,直至我们将数据准备好。
            profile.user = user

            # 用户是否提供图片(头像)?
            # 如果有,则要将其储存进数据库.
            if 'picture' in request.FILES:
                profile.picture = request.FILES['picture']

            #储存UserProfile数据.
            profile.save()

            # 更新registered信号,将其改为True,此信号将通知模板系统用户已完成注册.
            registered = True

        # 表单无效或出错
        # 将故障代码显示给终端及用户.
        else:
            print(user_form.errors, profile_form.errors)

    # 非HTTP POST请求, 那我们就仅仅渲染一下两个空白表单,以供用户输入.
    else:
        user_form = UserForm()
        profile_form = UserProfileForm()

    # 根据内容渲染模板.
    return render(request,
            'rango/register.html',
            {'user_form': user_form, 'profile_form': profile_form, 'registered': registered} )

接下来创建注册模板,创建templates/rango/register.html,加入如下内容:

templates/rango/register.html:

DOCTYPE html>
<html>
    <head>
        <title>Rangotitle>
    head>

    <body>
        <h1>注册Rangoh1>

        {% if registered %}
        Rango说: <strong>非常感谢您的注册!strong>
        <a href="/rango/">返回到首页.a><br />
        {% else %}
        Rango说: <strong>注册请点这里!strong><br />

        <form id="user_form" method="post" action="/rango/register/"
                enctype="multipart/form-data">

            {% csrf_token %}

            
            {{ user_form.as_p }}
            {{ profile_form.as_p }}

            
            <input type="submit" name="submit" value="注册" />
        form>
        {% endif %}
    body>
html>

视图和模板都好了,下面我们该处理URL映射,将它们都连到一起。编辑rango/urls.py,改成下面这样:

rango/urls.py:

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^about/$', views.about, name='about'),
    url(r'^category/(?P\w+)$', views.category, name='category'),
    url(r'^add_category/$', views.add_category, name='add_category'),
    url(r'^category/(?P\w+)/add_page/$', views.add_page, name='add_page'),
    url(r'^register/$', views.register, name='register'), # 新增内容在这里!
    )

最后,我们要修改首页模板(templates/rango/index.html),把“注册”链接放到首页中。请在 标签前添加以下内容:

templates/rango/index.html:

<a href="/rango/register/">注册a><br />

我们来看检查一下工作成果,在浏览器中输入:,你会看到下面这样的页面:

1_thumb

 

【未完待续】

本文版权归所有,欢迎转载,转载请注明作者和出处。谢谢!
作者:
首发:舍得学苑@博客园

 
阅读(1361) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~