七、Django2.1 搭建多用户的博客网站——维护个人详细信息

96
麦典威
0.3 2019.01.28 21:41* 字数 949

目录:Django 2.1 从零开始搭建博客网站系列

服务器环境搭建(选学)

小试牛刀——简单的博客网站

庖丁解牛——多用户的博客网站之用户模块

庖丁解牛——多用户的博客网站之文章模块

华丽转身——多用户的博客网站之扩展功能

项目源码下载:https://github.com/jt1024/lehehe

正文:

当完成了注册和登录之后,网站还会要求用户提供更多的个人信息,所以个人详细信息模块很有必要。

1、个人详细信息的数据模型和表单类

在 ./account/models.py 中新增 UserInfo

class UserInfo(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, unique=True)
    school = models.CharField(max_length=100, blank=True)
    company = models.CharField(max_length=100, blank=True)
    profession = models.CharField(max_length=100, blank=True)
    address = models.CharField(max_length=100, blank=True)
    aboutme = models.TextField(blank=True)
    
    def __str__(self):
        return "user:{}".format(self.user.username)

执行以下命令迁移数据

python manage.py make migrations
python manage.py migrate

此时数据库中新增数据表account_userinfo


account_userinfo.png

在 ./account/forms.py 中新增 UserInfoForm 和 UserForm

from .models import UserInfo

class UserInfoForm(forms.ModelForm):
    class Meta:
        model = UserInfo
        fields = ("school", "company", "profession", "address", "aboutme")

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ("email",)

特别注意:UserForm 的 fields 中不包括 username ,因为 username 一旦确定就不能随便修改,所以在用户详细信息中不允许修改这个字段。

2、个人详细信息的展示

在 ./account/views.py 中新增 myself方法

from django.contrib.auth.decorators import login_required
from .models import UserProfile, UserInfo
from django.contrib.auth.models import User

@login_required(login_url='/account/login')
def myself(request):
    user = User.objects.get(username=request.user.username)
    userprofile = UserProfile.objects.get(user=user)
    userinfo = UserInfo.objects.get(user=user)
    return render(request, "account/myself.html", {"user": user, "userprofile": userprofile, "userinfo": userinfo})

修改 ./account/views.py 中新增 user_register 方法

def user_register(request):
    if request.method == "POST":
        user_form = RegistrationForm(request.POST)
        userprofile_form = UserProfileForm(request.POST)
        if user_form.is_valid() * userprofile_form.is_valid():
            new_user = user_form.save(commit=False)
            new_user.set_password(user_form.cleaned_data['password'])
            new_user.save()
            new_profile = userprofile_form.save(commit=False)
            new_profile.user = new_user
            new_profile.save()
            UserInfo.objects.create(user=new_user)  # 新增,增加myself方法后,才添加这行代码
            return HttpResponse("注册成功!")
        else:
            return HttpResponse("抱歉,你不能注册")
    else:
        user_form = RegistrationForm()
        userprofile_form = UserProfileForm()
        return render(request, "account/register.html", {"form": user_form, "profile": userprofile_form})

在 ./account/urls.py 中新增如下代码

path('my-information/', views.myself, name='my_information'),

创建 ./templates/account/myself.html

{% extends "base.html" %}
{% block title %}my information{% endblock %}
{% block content %}
<div class="row text-center vertical-middle-sm">

    <h1>My Information</h1>
    <div class="row">

        <div class="col-md-6">
            <div class="row">
                <div class="col-md-4 text-right"><span>用户名:</span></div>
                <div class="col-md-8 text-left">{{user.username}}</div>
            </div>

            <div class="row">
                <div class="col-md-4 text-right"><span>邮箱:</span></div>
                <div class="col-md-8 text-left">{{user.email}}</div>
            </div>

            <div class="row">
                <div class="col-md-4 text-right"><span>生日:</span></div>
                <div class="col-md-8 text-left">{{userprofile.birth}}</div>
            </div>

            <div class="row">
                <div class="col-md-4 text-right"><span>电话:</span></div>
                <div class="col-md-8 text-left">{{userprofile.phone}}</div>
            </div>

            <div class="row">
                <div class="col-md-4 text-right"><span>毕业学校:</span></div>
                <div class="col-md-8 text-left">{{userinfo.school}}</div>
            </div>

            <div class="row">
                <div class="col-md-4 text-right"><span>工作单位:</span></div>
                <div class="col-md-8 text-left">{{userinfo.company}}</div>
            </div>

            <div class="row">
                <div class="col-md-4 text-right"><span>职业:</span></div>
                <div class="col-md-8 text-left">{{userinfo.profession}}</div>
            </div>

            <div class="row">
                <div class="col-md-4 text-right"><span>地址:</span></div>
                <div class="col-md-8 text-left">{{userinfo.address}}</div>
            </div>

            <div class="row">
                <div class="col-md-4 text-right"><span>个人介绍:</span></div>
                <div class="col-md-8 text-left">{{userinfo.aboutme}}</div>
            </div>

        </div>

        <div class="col-md-6">
            <p>picture</p>
        </div>
    </div>
</div>
{% endblock %}

由于之前注册的用户缺少字段,所以需要重新注册用户,然后登录,登录之后访问 http://127.0.0.1:8000/account/my-information/ 即可获得以下页面:

个人详细信息.png

3、个人详细信息的修改

在 ./account/views.py 中增加如下代码

from django.http import HttpResponseRedirect
from .forms import UserProfileForm, UserInfoForm, UserForm

@login_required(login_url='/account/login')
def myself_edit(request):
    userprofile = UserProfile.objects.get(user=request.user) if hasattr(request.user, 'userprofile') else UserProfile.objects.create(user=request.user)
    userinfo = UserInfo.objects.get(user=request.user) if hasattr(request.user, 'userinfo') else UserInfo.objects.create(user=request.user)
    if request.method == "POST":
        user_form = UserForm(request.POST)
        userprofile_form = UserProfileForm(request.POST)
        userinfo_form = UserInfoForm(request.POST)
        if user_form.is_valid() * userprofile_form.is_valid() * userinfo_form.is_valid():
            user_cd = user_form.cleaned_data
            userprofile_cd = userprofile_form.cleaned_data
            userinfo_cd = userinfo_form.cleaned_data
            request.user.email = user_cd['email']
            userprofile.birth = userprofile_cd['birth']
            userprofile.phone = userprofile_cd['phone']
            userinfo.school = userinfo_cd['school']
            userinfo.company = userinfo_cd['company']
            userinfo.profession = userinfo_cd['profession']
            userinfo.address = userinfo_cd['address']
            userinfo.aboutme = userinfo_cd['aboutme']
            request.user.save()
            userprofile.save()
            userinfo.save()
        return HttpResponseRedirect('/account/my-information/')
    else:
        user_form = UserForm(instance=request.user)
        userprofile_form = UserProfileForm(initial={"birth": userprofile.birth, "phone": userprofile.phone})
        userinfo_form = UserInfoForm(initial={"school": userinfo.school, "company": userinfo.company, "profession": userinfo.profession, "address": userinfo.address, "aboutme": userinfo.aboutme})
        return render(request, "account/myself_edit.html", {"user_form": user_form, "userprofile_form": userprofile_form, "userinfo_form": userinfo_form})

创建 ./templates/account/edit_my_infomation.html

{% extends "base.html" %}
{% block title %}my information{% endblock %}
{% block content %}
<div class="row text-center vertical-middle-sm">
    <h1>Edit My Information</h1>
    <div class="row">
        <div class="col-md-6">
            <form class="form-horizontal" action="." method="post">{% csrf_token %}
                <div class="row">
                    <div class="col-md-4 text-right"><span>用户名:</span></div>
                    <div class="col-md-8 text-left">{{user.username}}</div>
                </div>

                <div class="row">
                    <div class="col-md-4 text-right"><span>邮箱:</span></div>
                    <div class="col-md-8 text-left">{{user_form.email}}</div>
                </div>

                <div class="row">
                    <div class="col-md-4 text-right"><span>生日:</span></div>
                    <div class="col-md-8 text-left">{{userprofile_form.birth}}</div>
                </div>

                <div class="row">
                    <div class="col-md-4 text-right"><span>电话:</span></div>
                    <div class="col-md-8 text-left">{{userprofile_form.phone}}</div>
                </div>

                <div class="row">
                    <div class="col-md-4 text-right"><span>毕业学校:</span></div>
                    <div class="col-md-8 text-left">{{userinfo_form.school}}</div>
                </div>

                <div class="row">
                    <div class="col-md-4 text-right"><span>工作单位:</span></div>
                    <div class="col-md-8 text-left">{{userinfo_form.company}}</div>
                </div>

                <div class="row">

                    <div class="col-md-4 text-right"><span>职业:</span></div>
                    <div class="col-md-8 text-left">{{userinfo_form.profession}}</div>
                </div>

                <div class="row">
                    <div class="col-md-4 text-right"><span>地址:</span></div>
                    <div class="col-md-8 text-left">{{userinfo_form.address}}</div>
                </div>

                <div class="row">
                    <div class="col-md-4 text-right"><span>个人介绍:</span></div>
                    <div class="col-md-8 text-left">{{userinfo_form.aboutme}}</div>
                </div>

                <div class="row">
                    <input type="submit" class="btn btn-primary btn-lg" value="Submit">
                </div>
            </form>
        </div>
        <div class="col-md-6">
            <p>picture</p>
        </div>
    </div>
</div>
{% endblock %}

在 ./account/urls.py 中增加如下代码

path('edit-my-information/', views.myself_edit, name="edit_my_information"),

运行 Django,先登录一个账号,然后访问 http://127.0.0.1:8000/account/edit-my-information/,页面如图:

完善个人信息.png

点击 submit,页面如图:


完善个人信息成功.png