主要配置:
settings.py配置:
#数据库配置 import pymysql pymysql.install_as_MySQLdb() DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysite', 'HOST': '47.104.124.214', 'USER': 'root', 'PASSWORD': 'django', 'PORT': '3306', } } #session共享 # 配置session使用redis CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://47.104.124.214:6379', # 指明使用redis的1号数据库后面加/库名即可 "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "PASSWORD": "", }, }, } # session的存储配置 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_CACHE_ALIAS = 'default' # 设置session失效时间,单位为秒 SESSION_COOKIE_AGE = 60*5 # 邮件配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' EMAIL_PORT = 25 EMAIL_HOST_USER = '1335234172@qq.com' EMAIL_HOST_PASSWORD = 'nekxangczvxpgbii' # 注册有效期天数 CONFIRM_DAYS = 7
项目urls.py
from django.contrib import admin from django.urls import path,include from Registration import views urlpatterns = [ path('',include('Registration.urls')), path('admin/', admin.site.urls), path('Registration/',include('Registration.urls')), path('login/',views.login), path('register/',views.register), path('logout/',views.logout), path('captcha/', include('captcha.urls')), path('confirm/', views.user_confirm), ]
app admin.py
from django.contrib import admin from . import models # Register your models here. admin.site.register(models.User) admin.site.register(models.ConfirmString)
models.py
from django.db import models class User(models.Model): gender = (('male','男'),('female','女')) user = models.CharField(verbose_name=u'姓名',max_length=128,unique=True) passwd = models.CharField(verbose_name=u'密码',max_length=128) email = models.EmailField(verbose_name=u'邮箱',unique=True) sex = models.CharField(verbose_name=u'性别',max_length=32,choices=gender,default="男") c_time = models.DateTimeField(verbose_name=u'创建时间',auto_now_add=True) mod_date = models.DateTimeField(verbose_name=u'修改日期', auto_now=True) confiremd = models.BooleanField(verbose_name=u'确认',default=False) def __str__(self): return self.user class Meta: ordering = ['-c_time'] db_table = 'User' verbose_name = '用户表_[User]' verbose_name_plural = '用户表_[User]' #verbose_name=u'姓名',用于在admin界面添加正好时友好显示。不写添加账号会显示:字段名称 #unique唯一性 #auto_now无论是你添加还是修改对象,时间为你添加或者修改的时间。 #auto_now_add为添加时的时间,更新对象时不会有变动。 #choice只能选择'男'或者'女'.默认为男 #__str__是python的一个魔幻方法。作用于django管理界面用于将数据库中的记录展示为易读的字符串。 #Meta类用于定义表名称。默认表名称为'app名称_表名称',db_table用于指定表名 #ordering 用于指定一个字段,按照升序或降序对数据进行排序。指定的字段名称前加'-'表示递减,若没有加表示升序,若加'?'表示随机. #verbose_name用于在admin界面单数显示,verbose_name_plural复数形式显示。中文单数复数一般不做区别。 #verbose类似于User表在admin界面的显示形式。类似于别名 class ConfirmString(models.Model): code = models.CharField(max_length=256) user = models.OneToOneField('User',on_delete=models.CASCADE) c_time = models.DateTimeField(auto_now_add=True) #on_delete=models.CASCADE主外关系键中,级联删除,也就是当删除主表的数据时候从表中的数据也随着一起删除 def __str__(self): return self.user_id + ": "+self.code class Meta: ordering = ['-c_time'] db_table = 'ConfirmString' verbose_name = "确认表_[ConfirmString]" verbose_name_plural = "确认表_[ConfirmString]"
app urls.py
from django.urls import path from . import views urlpatterns = [ path('', views.index,name='index'), ]
views.py
from django.shortcuts import render,redirect from django.http import HttpResponse from . import models import hashlib import datetime from django.conf import settings def send_email(email, code): from django.core.mail import EmailMultiAlternatives subject = '来自bestyunyan.com的注册确认邮件' text_content = '''感谢注册bestyunyan.com,这里是王云龙的博客站点,专注于Python、Django学习技术的分享!\ 如果你看到这条消息,说明你的邮箱服务器不提供HTML链接功能,请联系管理员!''' html_content = ''' <p>感谢注册<a href="http://{}/confirm/?code={}" target=blank>www.bestyunyan.com</a>,\ 这里是王云龙的博客站点,专注于Python、Django学习技术的分享!</p> <p>请点击站点链接完成注册确认!</p> <p>此链接有效期为{}天!</p> '''.format('127.0.0.1', code, settings.CONFIRM_DAYS) msg = EmailMultiAlternatives(subject, text_content, settings.EMAIL_HOST_USER, [email]) msg.attach_alternative(html_content, "text/html") msg.send() #定义hash_code方法用于生成code def hash_code(s, salt='mysite'): h = hashlib.sha256() s += salt h.update(s.encode()) return h.hexdigest() def make_confirm_string(user): now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") code = hash_code(user.user, now) models.ConfirmString.objects.create(code=code, user=user,) return code def index(request): if not request.session.get('is_login',None): return redirect('/login/') # return HttpResponse('Hello, world. You\'re at the polls index.') return render(request,'index.html') def login(request): if request.session.get('is_login',None): return redirect('/') if request.method == "POST": user = request.POST.get('username') password = request.POST.get('password') message='请检查填写内容!' print('------user:%s,password:%s------'%(user,password)) if user.strip() and password: try: u=models.User.objects.get(user=user) #a=models.table_name.objects.get(xx=xx,yy=yy) #返回一个数据对象.获取数据对象的某一个属性字段值通过点的方式获取如: print('---数据库用户:%s,密码:%s,注册日期:%s'%(u.user,u.passwd,u.c_time)) except Exception as f: print(f) message = '用户不存在!' return render(request,'login/login.html',{'message':message}) if not u.confiremd: message = '用户未确认,请前往邮箱确认!' return render(request,'login/login.html',{'message':message}) if u.passwd == password: request.session['is_login'] = True request.session['user_id'] = u.id request.session['user_name'] = u.user request.session['user_email'] = u.email return redirect('/') else: message = '密码不正确' return render(request,'login/login.html',{'message':message}) return render(request,'login/login.html',{'message':message}) return render(request,'login/login.html') #通过下面的if语句,我们不允许重复登录: # if request.session.get('is_login',None): # return redirect("/") # request.session['is_login'] = True # request.session['user_id'] = user.id # request.session['user_name'] = user.name def register(request): if request.session.get('is_login',None): return redirect('/') if request.method == 'POST': user = request.POST.get('username') password1 = request.POST.get('passwd1') password2 = request.POST.get('passwd2') email = request.POST.get('email') sex = request.POST.get('sex') print('user:%s,password1:%s,password2:%s,email:%s,sex:%s'%(user,password1,password2,email,sex)) if password1 != password2: message='两次密码不相同' return render(request,'login/register.html') else: sameuser = models.User.objects.filter(user=user) if sameuser: message='该用户已经存在' return render(request,'login/register.html') sameemail =models.User.objects.filter(email=email) if sameemail: message='该邮箱已经被注册了' return render(request,'login/register.html') #django的操作数据库get方法是从数据库的取得一个匹配的结果,返回一个对象,如果记录不存在的话,它会报错。 #django的操作数据库filter方法是从数据库的取得匹配的结果,返回一个对象列表,如果记录不存在的话,它会返回[]。 models.User.objects.create(user=user,passwd=password1,email=email,sex=sex) new_user = models.User.objects.get(user=user) print('用户名称:%s密码:%s'%(new_user.user,new_user.passwd)) code = make_confirm_string(new_user) send_email(email, code) #通过make_confirm_string函数获取 message = '请前往邮箱确认!' print('code:%s,message:%s'%(code,message)) return render(request, 'login/confirm.html',{'message':message}) return render(request,'login/register.html') def logout(request): if not request.session.get('is_login',None): return redirect('/login/') request.session.flush() return redirect("/login/") def user_confirm(request): code = request.GET.get('code', None) message = '' try: confirm = models.ConfirmString.objects.get(code=code) except: message = '无效的确认请求!' return render(request, 'login/confirm.html', locals()) c_time = confirm.c_time now = datetime.datetime.now() print('---now:%s'%(now)) print('c_time:%s'%(c_time + datetime.timedelta(settings.CONFIRM_DAYS))) if str(now) > str(c_time + datetime.timedelta(settings.CONFIRM_DAYS)): confirm.user.delete() message = '您的邮件已经过期!请重新注册!' return render(request, 'login/confirm.html', locals()) else: confirm.user.confiremd = True confirm.user.save() confirm.delete() message = '感谢确认,请使用账户登录!' return render(request, 'login/confirm.html', locals())
cat confirm.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册确认</title> </head> <body> <h1 style="margin-left: 100px;">{{ message }}</h1> <script> window.setTimeout("window.location='/login/'",2000); </script> </body> </html>