django第一个小项目--用户注册及登录

Django的第一次动手

  自己用的是django2.0+python3.6版本的,在码代码的过程中,可能遇到一些bug,但这些bug百度上都能解决。

  1、是创建一个django项目,这里就略过了,创建了django项目之后,在Tools->Run manage.py Task...下输入startapp appname,我这里appname是users,  

  

之后系统会在项目中生成users的app。

  2、配置setting.py

  把users加入到setting.py的INSTALLED_APPS下:

  

  3、在项目中我们要创建一个扩展model,因为自带的用户表通常都不满足我们的需求,所以创建一个model来扩展我的用户表,但在创建model前,我们先连接数据库,model跟数据库有关联。

  我这里用的是mysql,so在settings.py中配置:

  

  然后在users app下的models.py写我们的UserPrsofile   model

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


class UserProfile(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='profile')
    telephone = models.CharField('Telephone',max_length=11,blank=True)
    org = models.CharField('Organization',max_length=50,blank=True)
    mod_date = models.DateTimeField('Last modified',auto_now=True)

    class Meta:
        verbose_name = 'profile'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.user

  在创建好model后,我们要迁移数据库,意思是创建model后我们要在数据库中生成对应的表。只需在Tools->Run manage.py Task...下输入:

  makemigrations

  migrate

  4、配置url

  在配置url前,我们需要在app下新建urls.py,你也可以不建,直接用项目下的urls.py,如果项目很大,配置的url就会很多,建议你还是在每个app下创建urls.py

from django.urls import re_path,path

from . import views

app_name = 'users'
urlpatterns = [

    re_path(r'register/$',views.RegisterView,name='register'),    #注册
    re_path(r'login/$',views.LoginView,name='login'),          #登录
    re_path(r'user/(?P<pk>\d+)/profile/$',views.Profile,name='profile'),      #个人信息
    re_path(r'user/(?P<pk>\d+)/profile_update/$',views.Profile_Update,name='profile_update'),  #更新个人信息
    re_path(r'user/(?P<pk>\d+)/pwd_change/$',views.pwd_change,name='pwd_change'),          #修改密码
    re_path(r'logout/$',views.LogoutView,name='logout'),          #退出登录
]

  注意,app下新建的urls.py文件django是找不到的,我们需要在项目中的urls.py下加入app下urls.py的路径

from django.contrib import admin
from django.urls import url,include

import xadmin

urlpatterns = [
    url(r'^xadmin/', xadmin.site.urls),
    url(r'^accounts/',include(("users.urls",'users'),namespace='users')),      #路径

  5.配置好urls.py后,我们要通过views.py来控制templates模板,最后展示出来

  配置views.py

from django.shortcuts import render,get_object_or_404
from django.views.generic import View
from django.http import HttpResponseRedirect,HttpResponse
from django.urls import reverse
from django.contrib import auth
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.contrib.auth.hashers import make_password,check_password

from .forms import LoginForm,RegisterForm,Porfile_UpdateFrom,PwdChangeFrom
from .models import UserProfile


#注册
def RegisterView(request):
    if request.method == 'POST':

        form = RegisterForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            email = form.cleaned_data['email']
            password = form.cleaned_data['password2']
            user = User.objects.create_user(username=username,email=email,password=password)
            user_profile = UserProfile(user=user)
            user_profile.save()
            return HttpResponseRedirect(reverse('users:login'))

    else:
        form = RegisterForm()
    return render(request,'users/registration.html',{'form':form})

#登录
def LoginView(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']

            user = auth.authenticate(username=username,password=password)
            if user is not None and user.is_active:
                auth.login(request,user)
                return HttpResponseRedirect(reverse("users:profile",args=[user.id]))
            else:
                #登录失败
                return render(request,'users/login.html',{'form':form,'message':'Wrong password.Please try again.'})
    else:
        form = LoginForm()
    return render(request,'users/login.html',{'form':form})

#个人信息
@login_required                     #判断用户是否登录
def Profile(request,pk):
    user = get_object_or_404(User,pk=pk)
    return render(request,'users/profile.html',{'user':user})

#更新用户信息
@login_required
def Profile_Update(request,pk):
    user = get_object_or_404(User,pk=pk)
    user_profile = get_object_or_404(UserProfile,pk=pk)

    if request.method == 'POST':
        form = Porfile_UpdateFrom(request.POST)
        if form.is_valid():
            user.first_name = form.cleaned_data['first_name']
            user.last_name = form.cleaned_data['last_name']
            user.save()

            user_profile.org = form.cleaned_data['org']
            user_profile.telephone = form.cleaned_data['telephone']
            user_profile.save()

            return HttpResponseRedirect(reverse('users:profile',args=[user.id]))
    else:
        file_profile = {
            'first_name':user.first_name,'last_name':user.last_name,
            'org':user_profile.org,'telephone':user_profile.telephone,
        }
        form = Porfile_UpdateFrom(file_profile)
    return render(request,'users/profile_update.html',{'form':form})

#密码修改
@login_required
def pwd_change(request,pk):
    user = get_object_or_404(User,pk=pk)

    if request.method == 'POST':
        form = PwdChangeFrom(request.POST)
        if form.is_valid():
            old_pwd = form.cleaned_data['old_pwd']
            password = form.cleaned_data['password2']

            # 校验密码 格式:check_password("123456","pbkdf2_sha25615000MAjic3nDGFoi$qbclz+peplspCbRF6uoPZZ42aJIIkMpGt6lQ+Iq8nfQ=")
            if check_password(old_pwd,user.password):
                user.password = make_password(password)         #密码加密
                user.save()
                return HttpResponseRedirect(reverse('users:login'))

            else:
                return render(request,"users/pwdchange.html",{'form':form,'msg':'old password error!'})
    else:
        form = PwdChangeFrom()
    return render(request,'users/pwdchange.html',{'form':form})

#退出
def LogoutView(request):
    return render(request,'users/logout.html')

  6、配置表单(让用户提交数据。django表单的作用是把用户的数据转化成Python对象格式,也可过滤数据)

  在users app下新建forms.py文件

import re
from django import forms
from django.contrib.auth.models import User


def email_check(email):
    pattern = re.compile(r"\"?([-a-zA-Z0-9.~?{}]+@\w+\.\w+)\"?")
    return re.match(pattern,email)

class Porfile_UpdateFrom(forms.Form):
    first_name = forms.CharField(label='First Name',max_length=50,required=False)
    last_name = forms.CharField(label='Last Name',max_length=50,required=False)
    org = forms.CharField(label='Organization',max_length=128,required=False)
    telephone = forms.CharField(label='Telephone',max_length=11,required=False)


class RegisterForm(forms.Form):
    username = forms.CharField(label='Username',max_length=20)
    email = forms.EmailField(label='email')
    password1 = forms.CharField(label='password1',widget=forms.PasswordInput)
    password2 = forms.CharField(label='password2',widget=forms.PasswordInput)

    def clean_username(self):
        username = self.cleaned_data.get('username')

        if len(username) < 6:
            raise forms.ValidationError("you username to short.")
        elif len(username) > 50:
            raise forms.ValidationError("you username to long.")
        else:
            filter_result = User.objects.filter(username__exact=username)
            if len(filter_result) > 0:
                raise forms.ValidationError("username is exist,please again.")

        return username

    def clean_email(self):
        email = self.cleaned_data.get('email')

        if email_check(email):
            filter_result = User.objects.filter(email__exact=email)
            if len(filter_result) > 0:
                raise forms.ValidationError("your email already exists.")
        else:
            raise forms.ValidationError("Please enter a valid email.")

        return email

    def clean_password1(self):
        password1 = self.cleaned_data.get('password1')

        if len(password1) < 6:
            raise forms.ValidationError("This password to short.")
        elif len(password1) >50:
            raise forms.ValidationError("This password to long.")

        return password1

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')

        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Password mismatch. Please enter again.")
        return password2

class LoginForm(forms.Form):
    username = forms.CharField(label='Username',max_length=20)
    password = forms.CharField(label='password',widget=forms.PasswordInput)

    def clean_username(self):
        username = self.cleaned_data.get('username')

        if email_check(username):
            filter_result = User.objects.filter(email__exact=username)
            if not filter_result:
                raise forms.ValidationError("This email does not exists.")
        else:
            filter_result = User.objects.filter(username__exact=username)
            if not filter_result:
                raise forms.ValidationError("This username does not exists.")

        return username

class PwdChangeFrom(forms.Form):
    old_pwd = forms.CharField(label='oldpwd',widget=forms.PasswordInput)
    password1 = forms.CharField(label='password1',widget=forms.PasswordInput)
    password2 = forms.CharField(label='password2',widget=forms.PasswordInput)

    def clean_password1(self):
        password1 = self.cleaned_data.get('password1')

        if len(password1) < 6:
            raise forms.ValidationError('password to short.')

        return password1

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')

        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Password mismatch. Please enter again.")

        return password2

  7、接下来就是配置templates模板(也就是我们的html)

  我们先在templates下新建一个文件夹users,把html文件放入该文件夹,便于管理

  然后在users新建我们的html文件

  registration.html  #注册

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% block content %}
<div class="form-wrapper">
   <form method="post" action="" enctype="multipart/form-data">
      {% csrf_token %}
      {% for field in form %}
           <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
             <p class="help">{{ field.help_text|safe }}</p>
        {% endif %}
           </div>
        {% endfor %}
      <div class="button-wrapper submit">
         <input type="submit" value="Submit" />
      </div>
   </form>
</div>
{% endblock %}
</body>
</html>

  login.html    

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{%  block content %}
<h2>Login</h2>
{%  if message %}
{{ message }}
{% endif %}
<div class="form-wrapper">
   <form method="post" action="" enctype="multipart/form-data">
      {% csrf_token %}
      {% for field in form %}
           <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
             <p class="help">{{ field.help_text|safe }}</p>
        {% endif %}
           </div>
        {% endfor %}
      <div class="button-wrapper submit">
         <input type="submit" value="Login" />
      </div>
   </form>
    <a href="{% url 'users:register' %}">Register</a>
</div>
{% endblock %}
</body>
</html>

  profile.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

</head>
<body>
{% block content %}
<h2>Account Info</h2>
<ul>
    <li>Username: {{ user.username }} </li>
    <li>Email: {{ user.email }} </li>
</ul>
<h2>My Profile</h2>

<ul>
    <li>First Name: {{ user.first_name }} </li>
    <li>Last Name: {{ user.last_name }} </li>
    <li>Organization: {{ user.profile.org }} </li>
    <li>Telephone: {{ user.profile.telephone }} </li>
</ul>

{% if user.is_authenticated %}
<a href="{% url 'users:profile_update' user.id %}">Edit</a>
| <a href="{% url 'users:pwd_change' user.id %}">Change Password </a>
| <a href="{% url 'users:logout' %}">Logout</a>
{% endif %}

{% endblock %}
</body>
</html>

  profile_update.html

{% block content %}
<h2>Account Info</h2>
<ul>
    <li>Username: {{ user.username }} </li>
    <li>Email: {{ user.email }} </li>

</ul>
<h2>Update My Profile</h2>

<div class="form-wrapper">
   <form method="post" action="" enctype="multipart/form-data">
      {% csrf_token %}
      {% for field in form %}
           <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
             <p class="help">{{ field.help_text|safe }}</p>
        {% endif %}
           </div>
        {% endfor %}
      <div class="button-wrapper submit">
         <input type="submit" value="Update" />
      </div>
   </form>
</div>

<a href="{% url 'users:logout' %}">Logout</a> |
      <a href="{% url 'users:pwd_change' user.id %}">Password change</a>

{% endblock %}

  pwdchange.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% block content %}
<h2>Password Change</h2>

<div class="form-wrapper">
   <form method="post" action="" enctype="multipart/form-data">
      {% csrf_token %}
      {% for field in form %}
           <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
             <p class="help">{{ field.help_text|safe }}</p>
        {% endif %}
           </div>
        {% endfor %}
   {{ msg }}
      <div class="button-wrapper submit">
         <input type="submit" value="Update" />
      </div>
   </form>
</div>

    <a href="{% url 'users:profile' user.id %}">profile</a>
    <a href="{% url 'users:logout' %}">Logout</a>
{% endblock %}

</body>
</html>

  8、结果展示

注册

用户信息

更新用户信息

更改密码

 总结一下:

  这里大部分代码都是来源于大江狗博客下项目的代码,写这篇主要是给自己做个笔记,总之在大江狗的微信公众号下也学到了知识,挺感谢大江狗的,如果没有大江狗博客,可能我现在还处于一头雾水的状态吧。感谢感谢!

猜你喜欢

转载自www.cnblogs.com/c-pyday/p/10851327.html