五、登录功能
1、首页和登录页面配置
将首页的index.html和登录页面login.html前端文件拷贝到项目的templates文件夹内,如果需要前端初始文件请联系我QQ:779060694,。
然后在项目根目录下新建static文件夹,该文件夹用来存放一些前端的静态文件,将前端的静态文件(css、images、img、js、media)这些文件拷贝到该文件夹下。
然后在setting.py文件中配置静态文件的访问路径:
1 STATICFILES_DIRS = ( 2 os.path.join(BASE_DIR, 'static'), 3 )
然后修改首页index.html和登录页面login.html初始文件中的静态文件访问路径,使用ctrl+f查找出所有的'../',然后ctrl+r全部替换为'/static/'。
现在开始在url.py文件中配置首页的访问url和登录页面的访问url:
1 from django.views.generic import TemplateView 2 3 urlpatterns = [ 4 path('', TemplateView.as_view(template_name='index.html'), name='index'), # 首页 5 path('login/', TemplateView.as_view(template_name='login.html'), name='login'), # 登录 6 ]
在index.html文件中修改跳转到登录页面的url,初始文件中将登录和注册都注释了,需要取消注释,然后修改跳转url:
现在就可以可以访问首页和登录页面了:http://127.0.0.1:8000/
2、后端用户登录接口
2.1 编写登录接口
在users/views.py文件中编写登录的接口:
1 from django.contrib.auth import authenticate, login 2 3 # Create your views here. 4 5 def user_login(request): 6 if request.method == 'POST': 7 # 获取用户提交的用户名和密码 8 user_name = request.POST.get('username', None) 9 pass_word = request.POST.get('password', None) 10 11 # 通过django的authenticate方法获取user对象,也就是验证用户是否存在 12 user = authenticate(username=user_name, password=pass_word) 13 14 if user is not None: 15 # 验证通过,通过django的login方法去登录,然后返回首页 16 login(request, user) 17 return render(request, 'index.html') 18 else: 19 return render(request, 'login.html', {'msg': '用户名或密码错误'}) 20 21 elif request.method == 'GET': 22 return render(request, 'login.html')
2.2 修改登录的url
在urls.py文件中修改登录页面的url:
1 from users import views 2 3 urlpatterns = [ 4 path('login/', views.user_login, name='login'), # 登录 5 ]
3、前端登录页面配置
在login.html文件中修改如下内容,与后端接口对接:
然后修改index.html文件中顶部登录注册按钮在登录状态下隐藏的问题,也就是未登录状态下显示登录注册按钮,登录状态下显示用户姓名和个人中心:
4、后端登录接口完善,增加邮箱登录和form表单验证
同时需要邮箱和用户名登录,需要自定义authenticate方法,在users/views中重写ModelBackend类中的方法authenticate:
1 from django.contrib.auth.backends import ModelBackend 2 from django.db.models import Q 3 4 from .models import UserProfile 5 6 # Create your views here. 7 8 9 class CustomBackend(ModelBackend): 10 """邮箱用户名同时登录验证方法""" 11 # 重写authenticate方法实现用户名、邮箱都可以登录 12 def authenticate(self, request, username=None, password=None, **kwargs): 13 try: 14 # 同时查询用户名和邮箱记录,使用Q并集查询 15 user = UserProfile.objects.get(Q(username=username)|Q(email=username)) 16 17 # 密码在数据库中是加密的,需要使用UserProfile继承的AbstractUser中的check_password方法 18 if user.check_password(password): 19 return user 20 except Exception as e: 21 return None
然后将重写后的CustomBackend类配置进setting.py文件中:
1 AUTHENTICATION_BACKENDS = ( 2 'users.views.CustomBackend', 3 )
现在就可以通过邮箱和用户名进行登录了。
继续完善登录接口,增加form表单验证,在users下新建form.py文件,添加需要表单验证的字段:
1 from django import forms 2 3 4 class LoginForm(forms.Form): 5 """登录表单验证""" 6 # required=True用户名和密码不能为空 7 username = forms.CharField(required=True) 8 password = forms.CharField(required=True, min_length=5)
继续完善登录接口,将函数的形式改成类的形式,通过form表单进行验证,先把函数形式改成类的形式:
1 class LoginView(View): 2 """登录""" 3 def get(self, request): 4 return render(request, 'login.html') 5 6 def post(self, request): 7 # form实例化 8 login_form = LoginForm(request.POST) 9 if login_form.is_valid(): 10 # form验证通过,获取用户提交的用户名和密码 11 user_name = request.POST.get('username', None) 12 pass_word = request.POST.get('password', None) 13 14 # 通过django的authenticate方法获取user对象,也就是验证用户是否存在 15 user = authenticate(username=user_name, password=pass_word) 16 17 if user is not None: 18 # 验证通过,通过django的login方法去登录,然后返回首页 19 login(request, user) 20 return render(request, 'index.html') 21 else: 22 # 验证不通过,返回登录页面,并将错误信息返回回去显示 23 return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form}) 24 else: 25 return render(request, 'login.html', {'login_form': login_form})
修改登录接口的url:
1 from users.views import LoginView 2 3 urlpatterns = [ 4 path('login/', LoginView.as_view(), name='login'), # 登录 5 ]
5、前端错误提示信息修改
登录失败后,前端需要有错误信息提示,login.html修改地方如下: