1. 程式人生 > >web後端--Django學習筆記05

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令牌。