第四天作业
1、models
from django.db import models class School(models.Model): name = models.CharField(max_length=20) address = models.CharField(max_length=20) establish_date = models.DateField() class Meta: db_table = 'schools' class Student(models.Model): name = models.CharField(max_length=20) age = models.IntegerField() score = models.FloatField() school = models.ForeignKey(School,on_delete=models.CASCADE) class Meta: db_table = 'students'
2、views
#school_view.py from django.shortcuts import render from homeworkapp.models import School def go_add_school(request): return render(request,'add_school.html') def add_school(request): schname = request.POST["schname"] schaddress = request.POST["schaddress"] schdate = request.POST["schdate"] school = School.objects.create(name=schname,address=schaddress,establish_date=schdate) return render(request,'add_school.html',{"new_school":school})
#students_view.py from django.http import HttpResponseRedirect from django.shortcuts import render, redirect from django.urls import reverse from homeworkapp.models import School, Student def go_add_student(request): schools = School.objects.all() return render(request,'add_student.html',locals()) # 添加学生 def add_student(request): stuname = request.POST["stuname"] stuage = request.POST["stuage"] stuscore = request.POST["stuscore"] school_id = request.POST["school"] School.objects.create(name=stuname,age=stuage,score=stuscore,school_id=school_id) return HttpResponseRedirect('/homework/allstudents/') # 重定向 # 显示所有学生信息 def show_all_students(request): students = Student.objects.all() return render(request, 'all_students.html', {"students": students}) def detail_student(request,stuid): student = Student.objects.get(id=stuid) return render(request,'student_detail.html',locals())
3、templates
<!add_school.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加学校</title> </head> <body> {% if new_school %} <h3> <span style="color:red">{{ new_school.name }}</span>添加成功!</h3> {% endif %} <form action="/homework/addschool/" method="post"> {% csrf_token %} 学校名称:<input type="text" name="schname"><br/> 学校地址:<input type="text" name="schaddress"><br/> 建校日期:<input type="date" name="schdate"/> <br/> <input type="submit" value="创建学校"/> </form> <br/> <a href="/homework/gostudent/">添加学生</a> </body> </html>
<!all_studdents.html> <!add_student.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加学生页面</title> </head> <body> <form action="/homework/addstudent/" method="post"> {% csrf_token %} 新生姓名:<input type="text" name="stuname"/> <br/> 新生年龄:<input type="text" name="stuage"/> <br/> 新生成绩:<input type="text" name="stuscore"/> <br/> 所属学校:<select name="school"> {% for school in schools %} <option value="{{ school.id }}">{{ school.name }}</option> {% endfor %} </select> <br/> <input type="submit" value="添加学生"/> </form> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>所有学生信息</title> </head> <body> <table border="1" align="center"> <thead> <tr> <th>学号</th> <th>姓名</th> <th>年龄</th> <th>成绩</th> <th>学校</th> </tr> </thead> <tbody> {% for student in students %} <tr> <td>{{ student.id }}</td> <td> <a href="{% url 'home:detail' student.id %}"> {{ student.name }} </a></td> <td>{{ student.age }}</td> <td>{{ student.score }}</td> <td>{{ student.school.name }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
<!student_detail.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{ student.name }}</title> </head> <body> <form action="" method="post"> 学号:<input type="text" value="{{ student.id }}" readonly/> <br/> 姓名:<input type="text" value="{{ student.name }}"/> <br/> 年龄:<input type="text" value="{{ student.age }}"/> <br/> 成绩:<input type="text" value="{{ student.score }}"/> <br/> 学校:<input type="text" value="{{ student.school.name }}"/> <br/> <input type="submit" value="修改"/> </form> </body> </html>
4、urls
#homeworke/urls.py 子路由 from django.urls import path from homeworkapp.views.school_views import * from homeworkapp.views.student_view import * app_name = "homeworkapp" urlpatterns = [ path('goschool/',go_add_school), path('addschool/',add_school), path('gostudent/',go_add_student), path('addstudent/',add_student), path('student/<stuid>/',detail_student,name="detail"), path('allstudents/',show_all_students),
#urls.py 总路由 from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path('homework/',include('homeworkapp.urls',namespace="home")), path('reverse/',include('reverseapp.urls',namespace="rev")), ]
一:模型外键自关联(引用)
当一个表中的记录存在层级关系时,使用外键自引用。 模型中创建外键自引用,使用'self'或'本模型类名称' models.ForeignKey('self',on_delete=models.CASCADE,null=True) 或 models.ForeignKey('本模型类名称',on_delete=models.CASCADE,null=True)
1、创建"老板"(没有对应的上级记录)
将外键自关联字段设置为Noneemp1 = Emp.objects.create(name="马云",parent_emp=None)
2、创建下层记录,将外键关联引用字段与上级记录关联
方式一:使用实例化对象关联emp2 = Emp.objects.create(name='张三',parent_emp=emp1)
方式二:使用外键值关联emp3 = Emp.objects.create(name='李四',parent_emp_id=2)
3、获取上级记录
例如:查询6号员工的直属领导 emp = Emp.objects.get(id=6) # 查询6号员工 manager = Emp.objects.get(id=emp.parent_emp_id) # 查询直属领导
4、删除上级记录后,所关联的下级记录也会级联删除
emp = Emp.objects.get(id=2)emp.delete()
1、models
from django.db import models class Emp(models.Model): name = models.CharField(max_length=20) age = models.IntegerField() sex = models.CharField(max_length=10) hire_date = models.DateField() salary = models.FloatField() parent_emp = models.ForeignKey('self',on_delete=models.CASCADE,null=True) #外键使用self关联自己 class Meta: db_table = 'emp' class Official(models.Model): name = models.CharField(max_length=20) sex = models.CharField(max_length=10) parent_official = models.ForeignKey('Official',on_delete=models.CASCADE,null=True)#使用自生类名关联 class Meta: db_table = 'officials'
2、Terminal
rosoft Windows [版本 10.0.17763.55] (c) 2018 Microsoft Corporation。保留所有权利。 C:\python\DjangoDay5> python manage.py makemigrations Migrations for 'selfapp': selfapp\migrations\0001_initial.py - Create model Emp - Create model Official C:\python\DjangoDay5>python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, selfapp, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying selfapp.0001_initial... OK Applying sessions.0001_initial... OK C:\python\DjangoDay5>python manage.py shell Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from selfapp.models import * >>> emp1 = Emp.objects.create(name="马云",age=55,sex="man",hire_date='1995-09-05',salary=10000,parent_emp=None) >>> emp2 = Emp.objects.create(name="马利",age=45,sex="woman",hire_date='199 8-09-05',salary=8000,parent_emp=emp1) >>> emp3 = Emp.objects.create(name="李四",age=48,sex="man",hire_date='1998- 11-05',salary=9000,parent_emp=emp1) >>> emp4 = Emp.objects.create(name="张三",age=38,sex="man",hire_date='2008- 11-05',salary=5000,parent_emp_id=3) >>> emp5 = Emp.objects.create(name="小红",age=28,sex="man",hire_date='2008- 11-05',salary=5000,parent_emp_id=4) #查询下级成员 >>> emp = Emp.objects.get(id=1) >>> emp.name '马云' >>> emps = Emp.objects.filter(parent_emp=emp) >>> for e in emps: ... print(e.name) ... 马利 李四 >>> emps = Emp.objects.filter(parent_emp_id=1) >>> for e in emps: ... print(e.name) ... ) 马利 李四 #查询上级 >>> emp2 = Emp.objects.get(id=5) >>> emp2.name '小红' >>> manager = Emp.objects.get(id=emp2.parent_emp_id) >>> manager.name '张三' >>> manager = Emp.objects.filter(id=emp2.parent_emp_id) >>> manager = Emp.objects.get(id=emp2.parent_emp_id) >>> manager.name '张三' >>> emp = Emp.objects.get(id=1) >>> emp.delete() #级联删除 (5, {'selfapp.Emp': 5}) Official模型 >>> o1 =Official(name='zs',sex='boy',parent_official=None) #创建顶级对象 >>> o1.save() >>> o2 =Official.objects.create(name='ls',sex='boy',parent_official=o1) #创建一级对象,父级为o1 >>> o3 =Official.objects.create(name='ww',sex='boy',parent_official=o2) #创建二级对象,父级为o2 >>> o1 = Official.objects.get(id=1) #获取对象 >>> o1.delete() #删除,会级联删除 (3, {'selfapp.Official': 3}) >>>
3、mysql
ywh@ubuntu:~$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.7.24-0ubuntu0.16.04.1 (Ubuntu) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> drop database mydb; Query OK, 11 rows affected (0.09 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.00 sec) mysql> create database mydb default character set utf8; Query OK, 1 row affected (0.00 sec) mysql> use mydb Database changed mysql> show tables; Empty set (0.00 sec) mysql> show tables; +----------------------------+ | Tables_in_mydb | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | django_admin_log | | django_content_type | | django_migrations | | django_session | | emp | | officials | +----------------------------+ 12 rows in set (0.00 sec) mysql> select * from emp; +----+--------+-----+-----+------------+--------+---------------+ | id | name | age | sex | hire_date | salary | parent_emp_id | +----+--------+-----+-----+------------+--------+---------------+ | 1 | 马云 | 55 | man | 1995-09-05 | 10000 | NULL | +----+--------+-----+-----+------------+--------+---------------+ 1 row in set (0.00 sec) mysql> select * from emp; +----+--------+-----+-------+------------+--------+---------------+ | id | name | age | sex | hire_date | salary | parent_emp_id | +----+--------+-----+-------+------------+--------+---------------+ | 1 | 马云 | 55 | man | 1995-09-05 | 10000 | NULL | | 2 | 马利 | 45 | woman | 1998-09-05 | 8000 | 1 | | 3 | 李四 | 48 | man | 1998-11-05 | 9000 | 1 | | 4 | 张三 | 38 | man | 2008-11-05 | 5000 | 3 | +----+--------+-----+-------+------------+--------+---------------+ 4 rows in set (0.00 sec) mysql> select * from emp; +----+--------+-----+-------+------------+--------+---------------+ | id | name | age | sex | hire_date | salary | parent_emp_id | +----+--------+-----+-------+------------+--------+---------------+ | 1 | 马云 | 55 | man | 1995-09-05 | 10000 | NULL | | 2 | 马利 | 45 | woman | 1998-09-05 | 8000 | 1 | | 3 | 李四 | 48 | man | 1998-11-05 | 9000 | 1 | | 4 | 张三 | 38 | man | 2008-11-05 | 5000 | 3 | | 5 | 小红 | 28 | man | 2008-11-05 | 5000 | 4 | +----+--------+-----+-------+------------+--------+---------------+ 5 rows in set (0.00 sec) mysql> select * from emp; #删除后查询 Empty set (0.00 sec) mysql> select * from officials; +----+------+-----+--------------------+ | id | name | sex | parent_official_id | +----+------+-----+--------------------+ | 1 | zs | boy | NULL | +----+------+-----+--------------------+ 1 row in set (0.02 sec) mysql> select * from officials; +----+------+-----+--------------------+ | id | name | sex | parent_official_id | +----+------+-----+--------------------+ | 1 | zs | boy | NULL | | 2 | ls | boy | 1 | | 3 | ww | boy | 2 | +----+------+-----+--------------------+ 3 rows in set (0.00 sec) mysql> select * from officials; #删除后查询为空 Empty set (0.00 sec)
二:URL反向解析
通过反向解析URL,可以在不改变模板链接路径的情况下,路由可以变化。 URL反向解析的实现: 第一步:设置命名空间 include('子路由模块路径',namespace="在此设置命名空间")
第二步:在path()函数的第三个name关键字参数中指定名称 path('路由地址/',视图函数名,name="在此设置name"),
第三步:在子路由(应用中的urls.py)中设置app_name app_name = "最好设置为应用名"
如何在模板中使用反向解析?{% url 'namespace名称:name名称' 参数1 参数2 ... %}
三:服务端跳转(转发)和客户端跳转(重定向)
服务端跳转(转发):将客户端发送的请求在后台服务器进行传递转发。 请求参数可以在后台传递,浏览器的URL地址不变。 实现服务端跳转:返回HttpResponse;返回render()。
客户端跳转(重定向):客户端向服务端发送两次不同的请求。 浏览器的URL地址改变。 实现客户端跳转: 方式一: HttpResponseRedirect('重定向的URL') 方式二: redirect()与reverse()结合使用,请思考?
四:CSRF
CSRF:跨网站请求伪造 如果开启了CsrfViewMiddleware中间件,则每次post请求都会检查令牌(token)是否 正确。 在表单中使用{% csrf_token %}标签,可以动态生成token令牌。