一、第十天作业
使用中间件完成一个随机抽奖的场景,每次发出请求后,产生一个1~100的随机数, 如果随机数的值大于90,则跳转到中奖页面,显示“恭喜,您中奖了”,否则返回给 客户端一个文本“抱歉,本次未中奖”。
1.1代码演示
1、mymiddleware
#mymiddleware/mymiddleware.py from django.http import HttpResponse from django.utils.deprecation import MiddlewareMixin import random class PrizeMiddleware(MiddlewareMixin): def process_request(self,request): number = random.randint(1,100) print("number=",number) if number<=90: return HttpResponse("<h3 style='color:red'>抱歉,本次未中奖</h3>") request.prize_number = number #动态添加一个属性
2、views
from django.shortcuts import render def prize_view(request): return render(request,'homeworkapp/congratulation.html')
3、templates
<!homeworkapp/congratulation.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>中奖页面</title> </head> <body> <h3>恭喜,您中奖了,中奖数字为:{{ request.prize_number }}</h3> </body> </html>
4、urls
#子路由 from django.urls import path from homeworkapp.views import prize_view urlpatterns = [ path('prize/',prize_view), ] #总路由 from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path('homeworkapp/',include('homeworkapp.urls')),
二、Django类视图
类视图可以封装处理不同请求的方法,自定义类视图需要继承 "from django.views import View"类,在类中实现自己要处理请求的方法, eg:get(self,request)、post(self,request)
由于View类有很多子类,所以也可以继承View的某些子类实现类视图。例如: 继承TemplateView类,可以通过template_name类属性指定模板; 继承RedirectView类,可以通过pattern_name指定重定向的路径(namespace:name)。
2.1 代码演示
1、views
from django.http import HttpResponse, JsonResponse from django.shortcuts import render, redirect from django.urls import reverse from django.views import View from django.views.generic import TemplateView, RedirectView from viewapp.forms import RegForm # def go_welcome(request,regname): # return render(request,'viewapp/welcome.html',locals()) class HelloView(View): def get(self,request): return HttpResponse("<h3 style='color:red'>欢迎学习类视图~~~</h3>") def post(self,request): username = request.POST["username"] password = request.POST["pwd"] return JsonResponse({"yourname":username,"yourpwd":password}) class RegisterView(View): def get(self,request): regform = RegForm() return render(request,'viewapp/register.html',locals()) def post(self,request): regform = RegForm(request.POST) # 接收表单数据,并封装到RegForm对象中 if regform.is_valid(): regname = regform.cleaned_data["regname"] regpwd = regform.cleaned_data["regpwd"] print("模拟插入数据库,注册用户名是:",regname,";注册密码是:",regpwd) return redirect(reverse("viewapp:mytemplate",args=(regname,))) else: return HttpResponse("<h3 style='color:red'>表单数据没有通过验证!</h3>") class MyTemplateView(TemplateView): template_name = "viewapp/welcome.html" #指定模板路径 def get(self,request,regname): print("get接收到参数了:",regname) return render(request, 'viewapp/welcome.html', locals()) class MyRedirectView(RedirectView): pattern_name = "viewapp:reg" # 指定重定向路径,pattern_name保存的是重定向路径
2、forms.py
from django import forms class RegForm(forms.Form): regname = forms.CharField(label="注册用户名",max_length=10) regpwd = forms.CharField(label="注册密码",max_length=8,widget=forms.PasswordInput())
3、templates
<!register.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册页面</title> </head> <body> <form action="{% url 'viewapp:reg' %}" method="post"> {% csrf_token %} {{ regform.as_p }} <input type="submit" value="注册"/> </form> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>欢迎页面</title> </head> <body> <h3>欢迎,{{ regname }},您已经注册成功!</h3> </body> </html>
4、urls
#子路由 from django.urls import path from viewapp.views import * app_name = "viewapp" urlpatterns = [ # path('welcome/<regname>/',go_welcome,name="welcome"), path('hello/',HelloView.as_view(),name="hello"), path('register/',RegisterView.as_view(),name="reg"), path('mytemplate/<regname>/',MyTemplateView.as_view(),name="mytemplate"), path('yourredirect/',MyRedirectView.as_view(),name="yourredirect"), ] #总路由 path('viewapp/',include('viewapp.urls',namespace="viewapp")),
三、多级评论案例
模型自关联+递归 详细见代码
1、views
from django.db import models class Article(models.Model): title = models.CharField(max_length=20,verbose_name="文章标题") content = models.TextField(verbose_name="文章内容") publishdate = models.DateField(verbose_name="发表日期") def __str__(self): return self.title class Meta: db_table = "articles" verbose_name = "文章模型" verbose_name_plural = verbose_name class Comment(models.Model): content = models.CharField(max_length=100,verbose_name="评论内容") article = models.ForeignKey(Article,on_delete=models.CASCADE,verbose_name="评论的文章") parent_comment = models.ForeignKey('self',on_delete=models.CASCADE,null=True,blank=True,verbose_name="父级评论") comment_date = models.DateField(verbose_name="评论日期") def __str__(self): return self.content class Meta: db_table = "comments" verbose_name = "评论模型" verbose_name_plural = verbose_name ordering = ["comment_date"] # 按照评论时间排序
2、comment/comment_util.py
def create_comment_tree(article): comments = article.comment_set.all() # 将文章对应的所有评论查询出来 comment_tree = {} for comment in comments: # 遍历该文章的所有评论 if comment.parent_comment is None: # 如果该评论没有父评论(针对文章本身的评论) comment_tree[str(comment)] = {} else: find_parent_comment(comment,comment_tree) return comment_tree def find_parent_comment(comment,comment_tree): for p,v in comment_tree.items(): if p == str(comment.parent_comment): # 判断当前遍历的评论对象是否为comment的父评论对象 comment_tree[str(p)][str(comment)] = {} # 关联父评论对象与子评论对象 break else: find_parent_comment(comment,comment_tree[p])
3、views
from django.http import JsonResponse, HttpResponse from django.shortcuts import render from commentapp.models import Article from commentapp.comment.comment_util import create_comment_tree def find_comments(request,article_id): try: article_id = int(article_id) except: return HttpResponse("<h3 style='color:red'>文章编号错误!</h3>") article = Article.objects.get(id=article_id) comment_tree = create_comment_tree(article) print(comment_tree) return JsonResponse(comment_tree)
4、admin.py
from django.contrib import admin from commentapp.models import * admin.site.register([Article,Comment])
5、urls
#子路由 from django.urls import path from commentapp.views import find_comments urlpatterns = [ path('comments/<article_id>/',find_comments), ] #总路由 path('commentapp/',include('commentapp.urls')),