第一百零三节 上下文处理器
setting 中的上下文处理器,自己定义的上下文处理器应该放在这个列表里
models.py 代码
1 from django.db import models 2 from django.core.validators import MinLengthValidator 3 4 class User(models.Model): 5 username = models.CharField(max_length=100, validators=[MinLengthValidator(4)]) 6 password = models.CharField(max_length=16, validators=[MinLengthValidator(6)]) 7 telephone = models.CharField(max_length=11)
views.py 代码
1 from django.shortcuts import render, redirect, reverse 2 from django.http import HttpResponse 3 from django.views.generic import View 4 from book.forms import SignupForm, SigninForm 5 from book.models import User 6 from django.contrib import messages 7 8 def index(request): 9 # user_id = request.session.get('user_id') 10 # context = {} 11 # try: 12 # user = User.objects.get(pk=user_id) 13 # context['book_user'] = user 14 # except: 15 # pass 16 return render(request, 'index.html') 17 18 class SigninView(View): 19 def get(self, request): 20 return render(request, 'signin.html') 21 22 def post(self, request): 23 form = SigninForm(request.POST) 24 if form.is_valid(): 25 username = form.cleaned_data.get('username') 26 password = form.cleaned_data.get('password') 27 user = User.objects.filter(username=username, password=password).first() 28 if user: 29 request.session['user_id'] = user.id 30 return redirect(reverse('index')) 31 else: 32 messages.info(request, '用户名或者密码错误') 33 return redirect(reverse('signin')) 34 else: 35 # print(form.errors.get_json_data()) 36 errors = form.get_error() 37 for error in errors: 38 messages.info(request, error) 39 return redirect(reverse('signin')) 40 41 42 class SignupView(View): 43 def get(self, request): 44 return render(request, 'signup.html') 45 46 def post(self, request): 47 form = SignupForm(request.POST) 48 if form.is_valid(): 49 form.save() 50 return redirect(reverse('index')) 51 else: 52 errors = form.errors.get_json_data() 53 print(errors) 54 return redirect(reversed('signup')) 55 56 57 def blog_view(request): 58 return render(request, 'blog_view.html')
urls.py 代码
1 from django.urls import path 2 from book import views 3 from django.conf.urls.static import static 4 from django.conf import settings 5 6 urlpatterns = [ 7 path('', views.index, name = 'index'), 8 path('signin/', views.SigninView.as_view(), name='signin'), 9 path('signup/', views.SignupView.as_view(), name='signup'), 10 path('blog_view/', views.blog_view, name='blog_view'), 11 ]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 12 # static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT),配置上传文件的存储路径,返回的是一个列表
forms.py 表单模型代码
1 from django import forms 2 from book.models import User 3 4 class SignupForm(forms.ModelForm): 5 password_repeat = forms.CharField(max_length=16, min_length=6) 6 def clean(self): 7 cleaned_data = super(SignupForm, self).clean() 8 password = cleaned_data.get('password') 9 password_repeat = cleaned_data.get('password_repeat') 10 if password != password_repeat: 11 raise forms.ValidationError(message='两次密码输入不一致') 12 return cleaned_data 13 class Meta: 14 model = User 15 fields = "__all__" 16 17 18 class SigninForm(forms.ModelForm): 19 20 def get_error(self): 21 news_errors = [] 22 errors = self.errors.get_json_data() 23 for messages in errors.values(): 24 for message_dict in messages: 25 for key, message in message_dict.items(): 26 if key == 'message': 27 news_errors.append(message) 28 return news_errors 29 class Meta: 30 model = User 31 fields =["username", "password"] 32 error_messages = { 33 'username':{ 34 'min_length':'用户名最小长度不能小于4位', 35 }, 36 'password':{ 37 'min_length':'密码最小长度不能小于6位', 38 }, 39 }
context_processors.py 自定义上下文管理器代码
1 from book.models import User 2 3 def book_user(request): 4 user_id = request.session.get('user_id') 5 context = {} 6 if user_id: 7 try: 8 user = User.objects.get(pk=user_id) 9 context['book_user'] = user 10 except: 11 pass 12 return context
settings.py 设置改动部分代码
import sys INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'book', ] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'book.context_processors.book_user', # 自定义上下文处理器 'django.template.context_processors.media', 'django.template.context_processors.csrf', ], }, }, ] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'book_manager', 'USER':'root', 'PASSWORD':'', 'HOST':'localhost', 'PORT':3306, } } MEDIA_ROOT = os.path.join(BASE_DIR, 'medias') MEDIA_URL = '/media/'
base.html 父模板HTML代码
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>首页</title> 6 <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> 7 {% block head %} 8 {% endblock %} 9 </head> 10 <body> 11 <nav class="navbar navbar-default"> 12 <div class="container-fluid"> 13 <!-- Brand and toggle get grouped for better mobile display --> 14 <div class="navbar-header"> 15 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> 16 <span class="sr-only">Toggle navigation</span> 17 <span class="icon-bar"></span> 18 <span class="icon-bar"></span> 19 <span class="icon-bar"></span> 20 </button> 21 <a class="navbar-brand" href="#">Brand</a> 22 </div> 23 <!-- Collect the nav links, forms, and other content for toggling --> 24 <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> 25 <ul class="nav navbar-nav"> 26 <li class=""><a href="">首页 <span class="sr-only">(current)</span></a></li> 27 <li class=""><a href="{% url 'blog_view' %}">博客<span class="sr-only">(current)</span></a></li> 28 29 </ul> 30 31 <ul class="nav navbar-nav navbar-right"> 32 {% if book_user %} 33 <li><a href="#">{{ book_user.username }}</a></li> 34 {% else %} 35 <li><a href="{% url 'signin' %}">登录</a></li> 36 <li><a href="{% url 'signup' %}">注册</a></li> 37 {% endif %} 38 39 40 </ul> 41 </div><!-- /.navbar-collapse --> 42 </div><!-- /.container-fluid --> 43 </nav> 44 {% block body %}{% endblock body %} 45 </body> 46 </html>
index.html 首页HTML代码
1 {% extends 'base.html' %} 2 {% block body %} 3 首页 4 <img src="{{ MEDIA_URL }}abc.png" alt=""> 5 {% endblock %}
signin.html 登录页面HTML代码
1 {% extends 'base.html' %} 2 {% block head %} 3 <meta name="csrf-token" content="{{ csrf-token }}"> 4 {% endblock %} 5 {% block body %} 6 <form action="" method="post"> 7 <!-- <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">--> 8 <!-- django提供的csrf上下文管理器,可以使用在非表单中 --> 9 {% csrf_token %} 10 <table> 11 <tbody> 12 <tr> 13 <td>用户名:</td> 14 <td><input type="text" name="username"></td> 15 </tr> 16 <tr> 17 <td>密码:</td> 18 <td><input type="password" name="password"></td> 19 </tr> 20 <tr> 21 <td></td> 22 <td><input type="submit" value="提交"></td> 23 </tr> 24 <tr> 25 <td></td> 26 <td> 27 {% for message in messages %} 28 {{ message.tags }}{{ message }} 29 <!-- message.tags 显示错误消息的级别 --> 30 {% endfor %} 31 </td> 32 </tr> 33 </tbody> 34 </table> 35 </form> 36 {% endblock %}
signin.html 注册页面HTML代码
1 {% extends 'base.html' %} 2 {% block body %} 3 <form action="" method="post"> 4 <table> 5 <tbody> 6 <tr> 7 <td>用户名:</td> 8 <td><input type="text" name="username"></td> 9 </tr> 10 <tr> 11 <td>手机号码:</td> 12 <td><input type="text" name="telephone"></td> 13 </tr> 14 <tr> 15 <td>密码:</td> 16 <td><input type="password" name="password"></td> 17 </tr> 18 <tr> 19 <td>密码:</td> 20 <td><input type="password" name="password_repeat"></td> 21 </tr> 22 <tr> 23 <td></td> 24 <td><input type="submit" value="提交"></td> 25 </tr> 26 </tbody> 27 </table> 28 </form> 29 {% endblock %}