Django之博客系统:用户注册和Profile

前面章节介绍了用户的登录,退出。这一章将介绍用户的注册。首先需要创建一个表单来让用户填写用户名,密码等信息。创建UserRegistrationFrom表单。并指定model为User类

from django.contrib.auth.models import User

class UserRegistrationForm(forms.ModelForm):

    password=forms.CharField(label=u"密码")

    password2=forms.CharField(label=u"重复输入密码")

    class Meta:

        model=User

        fields=('username','first_name','email')

    def clean_password2(self):

        cd=self.cleaned_data

        if cd['password'] != cd['password2']:

            raise forms.ValidationError(u'密码不匹配')

        return cd['password2']

在这里定义了clean_password2用于校验两次输入的密码是否不相同,如果不同则抛出异常。这个函数在调用user_form.is_valid()的时候将会被触发调用

接下来在views.py中添加处理函数:

def register(request):

    if request.method == "POST":

        user_form=UserRegistrationForm(request.POST)

        if user_form.is_valid():

            new_user=user_form.save(commit=False)

            new_user.set_password(user_form.cleaned_data['password']) #使用set_password方法将用户的密码进行加密后再进行保存操作

            new_user.save()

            return render(request,'blog/register_done.html',{'new_user':new_user})

    else:

        user_form=UserRegistrationForm()

return render(request,'blog/register.html',{'user_form':user_form})

当用户注册成功,返回register_done页面,初始访问的时候返回register页面

在blog应用中的url中添加路由配置:

url(r'^register/$',views.register,name='register'),

在templates/blog下新添加register.html和register_done.html

register.html代码如下

{% extends "blog/base.html" %}

{% block title %}创建新用户{% endblock %}

{% block content %}

  <h1>创建新用户</h1>

  <p>请填写如下表单:</p>

  <form action="." method="post">

    {{ user_form.as_p }}

    {% csrf_token %}

    <p><input type="submit" value="Create my account"></p>

  </form>

{% endblock %}

register_done.html代码如下:

{% extends "blog/base.html" %}

{% block title %}欢迎{% endblock %}

{% block content %}

  <h1>欢迎 {{ new_user.first_name }}!</h1>

  <p>已经成功创建用户 <a href="{% url "login" %}">请登录</a>.</p>

{% endblock %}

在url中输入http://127.0.0.1:8000/account/register/进入注册界面

注册完成后提示注册成功,并附上了登录的链接

扩展用户模型:

到目前为止,我们所有的用户都是通过User类内置的元素来编辑的。但是User模型只有固定的一些字段。如果我们想扩展User的字段就需要创建一个profile模型来包含我们想增加的字段。并且和django中的User做一对一的关联

首先在models.py中添加如下代码:user一对一关联用户和profile。另外还定义了date_of_birth和photo字段,如果想要上传图片需要安装Pillow来管理图片。

class Profile(models.Model):

user=models.OneToOneField(settings.AUTH_USER_MODEL)

#通过OneToOneField将profile和User类关联起来

    date_of_birth=models.DateTimeField(blank=True,null=True)

    photo=models.ImageField(upload_to='users/%/Y/%/m/%/d',blank=True)

    def __str__(self):

        return 'Profile for user{}'.format(self.user.username)

class Profile_admin(admin.ModelAdmin):

    list_display = ['user','date_of_birth','photo']

在setting.py中添加图片的存放路径:这里设置存放在/media路径。MEDIA_URL 是管理用户上传的多媒体文件的主URL,MEDIA_ROOT是这些文件在本地保存的路径

MEDIA_URL='/media/'

MEDIA_ROOT=os.path.join(BASE_DIR,'media/')

在主urls.py中添加如下代码:

from django.conf import settings

from django.conf.urls.static import static

if settings.DEBUG:

    urlpatterns += static(settings.MEDIA_URL,

                        document_root=settings.MEDIA_ROOT)

下面开始进行数据库迁移:

zhf@zhf-maple:~/py_prj/mysite$ python manage.py makemigrations

Migrations for 'blog':

  blog/migrations/0005_profile.py

    - Create model Profile

zhf@zhf-maple:~/py_prj/mysite$ python manage.py migrate

Operations to perform:

  Apply all migrations: admin, auth, blog, contenttypes, sessions, taggit

Running migrations:

  Applying blog.0005_profile... OK

在admin.py中进行注册:

admin.site.register(Profile,Profile_admin)

如果我们需要用户在线编辑他们的profile,需要定义模型,在forms.py中添加如下代码:

class UserEditForm(forms.ModelForm):

    class Meta:

        model=User

        fields=("first_name","last_name","email")

 

class ProfileEditForm(forms.ModelForm):

    class Meta:

        model=Profile

        fields=('date_of_birth','photo')

这两个表单(forms)的功能:

  • UserEditForm:允许用户编辑它们的first name,last name, e-mail 这些储存在User模型(model)中的内置字段。
  • ProfileEditForm:允许用户编辑我们存储在定制的Profile模型(model)中的额外数据。用户可以编辑他们的生日数据以及为他们的profile上传一张照片。

在views,py的register函数中的new_user.save()后添加

profile=Profile.objects.create(user=new_user)。这给每个用户添加了一个profile对象。注意,在这段代码添加前的用户是没有这个profile对象的,只有这个profile对象添加之后的用户才有这个对象。

下面添加edit函数来编辑profile

@login_required(login_url='/account/login')

def edit(request):

    if request.method == 'POST':

        user_form=UserEditForm(instance=request.user,data=request.POST)

        profile_form=ProfileEditForm(instance=request.user.profile,data=request.POST,files=request.FILES)

        if user_form.is_valid() and profile_form.is_valid():

            user_form.save()

            profile_form.save()

    else:

        user_form=UserEditForm(instance=request.user)

        profile_form=ProfileEditForm(instance=request.user.profile)

return render(request,'blog/edit.html',{'user_form':user_form,'profile_form':profile_form})

我们使用login_required装饰器decorator是因为用户编辑他们的profile必须是认证通过的状态。在这个例子中,我们使用两个模型(model)表单(forms):UserEditForm用来存储数据到内置的User模型(model)中,ProfileEditForm用来存储额外的profile数据。为了验证提交的数据,通过is_valid()方法是否都返回True我们来检查每个表单(forms)。在这个例子中,我们保存两个表单(form)来更新数据库中对应的对象。

最后在blog应用中的urls.py中添加路由:

url(r'^edit/$', views.edit, name='edit'),

登录帐号后输入http://127.0.0.1:8000/account/edit/进入编辑

进入admin界面也可以看到添加的profile对象

 

posted @ 2018-03-24 16:30  red_leaf_412  阅读(3019)  评论(0编辑  收藏  举报