Django博客项目(一)—— 注册和登录页面

最近使用Django+Nginx+UWSGI的方式,实现了一个简单的个人博客项目。
主要功能包括注册、登录、发表博客、发表评论、博客列表及博客搜索、博客主页显示等等。
本文介绍首先实现的功能,也就是最基本的登录和注册功能。

效果图

首先看一下完成后的效果,以便于理解。
登录页面:
Django博客项目(一)—— 注册和登录页面_第1张图片
注册页面
Django博客项目(一)—— 注册和登录页面_第2张图片

配置文件中添加相关配置信息

修改settings.py文件

INSTALLED_APPS = [
	# 添加验证码
    'captcha',
]
DATABASES = {
	# 数据库使用的是Mysql
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'blog_ex',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': 3306,
    }
}
# 设置静态资源路径
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

# 图形验证码设置
# 格式
CAPTCHA_OUTPUT_FORMAT = u'%(text_field)s  %(image)s %(hidden_field)s'
# 干扰项设置
CAPTCHA_NOISE_FUNCTIONS = (
    'captcha.helpers.noise_null',  
    'captcha.helpers.noise_arcs',  
    'captcha.helpers.noise_dots', 
)
# 图片样式
CAPTCHA_IMAGE_SIZE = (100, 30)
CAPTCHA_BACKGROUND_COLOR = '#ffffff'
# 使用随机字符
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
# 字符个数  
CAPTCHA_LENGTH = 4  
CAPTCHA_TIMEOUT = 1  

还有几个注意事项:

  1. 最好使用一个新建的数据库来完成本项目。
  2. 如果代码执行过程中报错信息为缺少依赖库,那么根据报错信息进行安装即可。

创建模型,并在数据库中生成表

修改models.py文件,创建类,每个类对应数据库中的一张表。

from django.contrib.auth.models import AbstractUser
from django.db import models

# 用户信息
class UserRe(AbstractUser):
    phones = models.CharField(max_length=20, null=True)
    email = models.EmailField(null=True)
    gender = models.CharField(max_length=10)

    class Meta(AbstractUser.Meta):
        db_table = 'user_re'

# 博客分类
class BlogCategory(models.Model):
    cid = models.IntegerField(primary_key=True)
    cname = models.CharField(max_length=60)
    blogcount = models.IntegerField(default=0)

    class Meta:
        db_table = 'blog_category'

# 博客信息
class BlogPost(models.Model):
    id = models.IntegerField(primary_key=True)
    author = models.CharField(max_length=60)
    title = models.CharField(max_length=600)
    content = models.CharField(max_length=600)
    classname = models.CharField(max_length=60)
    replycount = models.IntegerField(default=0)
    addtime = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'blog_post'

# 回复信息
class BlogReply(models.Model):
    id = models.IntegerField(primary_key=True)
    bid = models.IntegerField()
    author = models.CharField(max_length=60)
    content = models.CharField(max_length=600)
    addtime = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'blog_reply'

创建完毕后,需要进行数据库迁移,才能在数据库中生成对应的表。

python manage.py makemigrations
python manage.py migrate

创建表单

如效果图所示,注册和登录界面都依赖表单来完成,用户相当于是在填写表单信息。如果填写的信息符合相关规范,提交就能通过,否则提示对应的错误信息。
添加forms.py文件,用于自定义实现登录表单和注册表单。

import re

from captcha.fields import CaptchaField
from django import forms
from django.core.exceptions import ValidationError

from App01.models import UserRe

# 验证密码是否符合规范
def check_password(pwd):
    if pwd.isdigit():
        raise ValidationError('密码不能只包含数字')

# 验证是否是合法手机号
def check_phone(phone_num):
    if not re.match(r'^(13[0-9]|14[156789]|15[0-3,5-9]|166|17[0135678]|18[0-9]|19[89])\d{4}\d{4}$', phone_num, re.I):
        raise ValidationError('无效的手机号')


# 自定义注册表单
class RegisterForm(forms.Form):
    username = forms.CharField(min_length=6, required=True, error_messages={
        'required': '用户名不能为空',
        'min_length': '用户名至少由6位字符组成'
    })
    password = forms.CharField(min_length=6,
                               max_length=12,
                               required=True,
                               validators=[check_password],
                               error_messages={
                                        'required': '密码不能为空',
                                        'min_length': '密码至少由6位字符组成',
                                        'max_length': '密码至多由12位字符组成',
                                        })
    confirm_password = forms.CharField(min_length=6,
                                       max_length=12,
                                       required=True,
                                       error_messages={
                                            'required': '密码不能为空',
                                            'min_length': '密码至少由6位字符组成',
                                            'max_length': '密码至多由12位字符组成',
                                            })
    email = forms.EmailField(error_messages={'invalid': '无效的邮箱格式'})
    phone = forms.CharField(required=True, validators=[check_phone])
    captcha = CaptchaField()

    def clean_username(self):
        username = self.cleaned_data.get('username')
        if UserRe.objects.filter(username=username).first():
            raise ValidationError('用户名重复')
        return username

    def clean(self):
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if password != confirm_password:
            raise ValidationError({'confirm_password': ['两次密码输入不匹配']})
        return self.cleaned_data

# 自定义登录表单
class LoginForm(forms.Form):
    username = forms.CharField(required=True, error_messages={'required': '用户名不能为空'})
    password = forms.CharField(required=True, error_messages={'required': '密码不能为空'})
    captcha = CaptchaField()

路由配置

修改urls.py文件,此处只列出注册和登录部分使用的路由信息。

from django.urls import path

from App01 import views

app_name = 'App01'
urlpatterns = [
    # 登录
    path('login/', views.user_login, name='login'),
    # 注册
    path('register/', views.user_register, name='register'),
    # 登出
    path('logout/', views.user_logout, name='logout'),
]

视图函数

修改views.py文件。我在项目中使用的是FBV(function base views)的方式,使用函数处理请求。还有另一种方式是CBV(class base views),使用类处理请求。

# 用户登录
def user_login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 使用自定义登录表单
        form = LoginForm(request.POST)
        user = authenticate(request, username=username, password=password)
        # 判断用户是否存在
        if user:
        	# 判断登录信息是否符合规范
            if form.is_valid():
                login(request, user)
                return redirect(reverse('App01:index'))
            else:
                return render(request, 'blog/login.html', locals())
        else:
            login_errors = '用户名或密码错误'
            return render(request, 'blog/login.html', locals())
    form = LoginForm()
    return render(request, 'blog/login.html', locals())

# 用户注册
def user_register(request):
    if request.method == 'POST':
    	# 使用自定义注册表单
        form = RegisterForm(request.POST)
        gender = request.POST.get('gender')
        # 判断表单验证是否通过
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            email = form.cleaned_data.get('email')
            phones = form.cleaned_data.get('phone')
            # 创建用户对象,存入数据库
            user = UserRe.objects.create_user(username=username, password=password, email=email, phones=phones, gender=gender)
            login(request, user)
            return redirect(reverse('App01:index'))
        else:
            return render(request, 'blog/register.html', locals())
    form = RegisterForm()
    return render(request, 'blog/register.html', locals())

# 用户注销登录
def user_logout(request):
    logout(request)
    return redirect(reverse('App01:index'))

前端HTML文件的部分代码示例

修改register.html,完成注册页面(此处只展示表单部分代码)

<form class="form-horizontal" action="{% url 'App01:register' %}" method="post">
          {% csrf_token %}
          <div class="control-group">
            <div class="controls">
              <h4>Register</h4>
            </div>
          </div>
          <div class="control-group">
            <label for="inputEmail" class="control-label">Username </label>
            <div class="controls">
              <input id="inputEmail" type="text" placeholder="Username" name="username" ><br>
              <span>
              	{# 出错时显示错误信息 #}
                {% for error in form.username.errors %}
                    <span>{{ error }}</span><br>
                {% endfor %}
              </span> <br>
            </div>
          </div>
          
 	{# 密码、邮箱、手机号写法同用户名类似,此处省略 #}

          <div class="control-group">
            <label for="inputCapcha" class="control-label">Captcha </label>
            <div class="controls">
              {{ form.captcha }}<span>{{ form.captcha.errors.0 }}</span><br>
            </div>
          </div>
          <div class="control-group">
            <div class="controls">
            <input type="submit" value="Register">
            </div>
          </div>
        </form>

总结

至此,个人博客的用户注册和登录界面就完成了。整个过程最重要的两部分就是创建模型和创建自定义表单类。这两步完成之后,剩下的就是在视图函数中进行调用了,如果对相关原理比较熟悉的话,实现起来还是很容易的。

你可能感兴趣的:(django,Python)