web後端--Django學習筆記05
第四天作業
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
[email protected]:~$ 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令牌。