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、结果展示
注册
用户信息
更新用户信息
更改密码
总结一下:
这里大部分代码都是来源于大江狗博客下项目的代码,写这篇主要是给自己做个笔记,总之在大江狗的微信公众号下也学到了知识,挺感谢大江狗的,如果没有大江狗博客,可能我现在还处于一头雾水的状态吧。感谢感谢!