ORM之学生管理
URL部分
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
# 学生管理
url(r'^student_list/', views.student_list,name="student_list"),
url(r'^add_student/', views.add_student,name="add_student"),
url(r'^delete_student/(\d+)', views.delete_student,name="delete_student"),
url(r'^edit_student/(\d+)', views.edit_student,name="edit_student"),
]
models部分
from django.db import models
# Create your models here.
"""
班级表
"""
class Class(models.Model):
id = models.AutoField(primary_key=True)
cname = models.CharField(max_length=32, null=True)
first_day = models.DateField()
def __str__(self):
return self.cname
"""
学生表
"""
class Student(models.Model):
id = models.AutoField(primary_key=True)
sname = models.CharField(max_length=32)
cid = models.ForeignKey(to="Class",to_field="id",related_name="students")
detail = models.OneToOneField("StudentDetail",null=True,related_name="stu")
def __str__(self):
return self.sname
"""
学生详细信息
"""
class StudentDetail(models.Model):
height = models.PositiveIntegerField()
email = models.EmailField()
memo = models.CharField(max_length=128, null=True)
views部分
from django.shortcuts import render, redirect, HttpResponse
from django.urls import reverse
from . import models
#展示学生
def student_list(request):
student_list = models.Student.objects.all
return render(request, "student_list.html", {"student_list": student_list})
# 添加学生
def add_student(request):
if request.method == "POST":
sname = request.POST.get("sname")
cid = request.POST.get("cid")
models.Student.objects.create(sname=sname, cid_id=cid)
return redirect(reverse("student_list"))
class_list = models.Class.objects.all()
return render(request, "add_student.html", {"class_list": class_list})
# 删除学生
def delete_student(request, sid):
models.Student.objects.filter(id=sid).delete()
return redirect(reverse("student_list"))
# 编辑学生
def edit_student(request, sid):
student_obj = models.Student.objects.get(id=sid)
if request.method == "POST":
sname = request.POST.get("sname")
cid = request.POST.get("cid")
student_obj.sname = sname
# 注意student_obj.cid在ORM里面表示的是一个班级的对象
student_obj.cid_id = cid
student_obj.save()
return redirect(reverse("student_list"))
class_list = models.Class.objects.all()
return render(request, "edit_student.html", {"class_list": class_list, "student": student_obj})
前端HTML部分
student_list(展示学生) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <a href="{% url "add_student" %}">添加学生</a> <table border="1"> <thead> <tr> <th>#</th> <th>id</th> <th>姓名</th> <th>班级</th> <th>操作</th> </tr> </thead> <tbody> {% for student in student_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ student.id }}</td> <td>{{ student.sname }}</td> <td>{{ student.cid.cname }}</td> <td> <a href="{% url 'delete_student' student.id%}">删除</a> <a href="{% url "edit_student" student.id %}">编辑</a> </td> </tr> {% endfor %} </tbody> </table> </body> </html> 添加学生(add_student) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <form action="{% url "add_student" %}" method="post"> {% csrf_token %} <label for=""> 学生姓名 <input type="text" name="sname"> </label> <label for="class_id">所在班级</label> <select name="cid" id="class_id"> {% for class in class_list %} <option value="{{ class.id }}">{{ class.cname }}</option> {% endfor %} </select> <p><input type="submit" value="提交"></p> </form> </body> </html> 编辑学生(edit_student) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <form action="{% url "edit_student" student.id %}" method="post"> {% csrf_token %} <input type="text" name="sname" value="{{ student.id }}" hidden> <p><input type="text" name="sname" value="{{ student.sname }}">学生姓名</p> <label for="class_id">所在班级</label> <select name="cid" id="class_id"> {% for class in class_list %} {% if student.cid.id == class.id %} <option value="{{ class.id }}">{{ class.cname }}</option> {% else %} <option value="{{ class.id }}">{{ class.cname }}</option> {% endif %} {% endfor %} </select> <p><input type="submit" value="提交"></p> </form> </body> </html>
基于对象的跨表查询
一对一查询(班级表和学生表)
正想查询(由学生表查询班级表)
查询学生的班级信息
models.Student.objects.first()
<Student: 大卫1>
models.Student.objects.first().cid 通过model类中的属性查找到对应的外键数据对象
<Class: 99期>
models.Student.objects.first().cid.cname
'99期'
models.Student.objects.first().cid_id #获取实际外键的值
反向查询(由班级表查询学生表)
查询班级的学生表
class_obj = models.Class.objects.first() # 获取第一个班级对象
class_obj.student_set.all() # 通过表名_set反向查询出所有的学生
<QuerySet [<Student: Student object>, <Student: Student object>]>
注意:
如果不在外键的字段中设置related_name的话,默认就用表名_set。
如果设置了related_name="students",反向查询时可直接使用students进行反向查询。
class_obj.students.all()
一对一查询
表结构设计
class Student(models.Model):
sname = models.CharField(max_length=32, verbose_name="学生姓名")
the_class = models.ForeignKey(to=Class, to_field="id", on_delete=models.CASCADE, related_name="students")
detail = models.OneToOneField(to="StudentDetail", null=True)
class StudentDetail(models.Model):
height = models.PositiveIntegerField()
weight = models.PositiveIntegerField()
email = models.EmailField()
正向查询(由学生信息表查询学生详情表)
>>> student_obj = models.Student.objects.first()
>>> student_obj.detail.email
'1@1.com'
反向查询(由学生详情表反向查询学生信息表)
>>> detail_obj = models.StudentDetail.objects.get(id=1)
>>> detail_obj.student.sname
'a'