学生管理系统
urls.py
url(r'^student_list/$',views.student_list,name="student_list"), url(r'^delete_student/(?P<sid>d+)/$',views.delete_student,name="delete_student"), url(r'^add_student/',views.add_student,name="add_student"), url(r'^edit_student/(?P<sid>d+)/$',views.edit_student,name="edit_student"),
视图部分
# 展示学生信息 def student_list(request): # 查找到所有学生 student_list = models.Student.objects.all() return render(request,"student_list.html",{"student_list":student_list}) # 删除学生信息 def delete_student(request,sid): # 从数据库里面取id值为sid的学生对象 models.Student.objects.filter(id=sid).delete() # 删除成功,跳转到student_list return redirect(reverse("student_list")) # 添加学生信息 def add_student(request): if request.method == "POST": sname = request.POST.get("sname") cid = request.POST.get("cid") # 取数据库创建 models.Student.objects.filter().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 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 student_obj.sname = sname 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})
前端部分
<!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> </head> <body> <h1>添加学生信息</h1> <form action="{% url 'add_student' %}" method="post"> {% csrf_token %} {# 跨站请求伪造保护 #} <label for="i1">学生姓名:</label> <input id="i1" type="text" value="" name="sname"> <label for="i2">所在班级:</label> <select name="cid" id="i2"> {% for class in class_list %} <option value="{{ class.id }}">{{ class.cname }}</option> {% endfor %} </select> <button type="submit">提交</button> <button><a href="{% url 'student_list' %}">取消</a></button> </form> </body> </html>
<!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> </head> <body> <button><a href="{% url 'add_student' %}/"> 添加 </a></button> <table border="1px"> <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> <button><a href="{% url 'edit_student' student.id %}"> 编辑 </a></button> <button><a href="{% url 'delete_student' student.id %}"> 删除 </a></button> </td> </tr> {% endfor %} </tbody> </table> </body> </html>
<!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> </head> <body> <h1>编辑学生信息</h1> <form action="{% url 'edit_student' student.id %}" method="post"> {% csrf_token %} {# 跨站请求伪造保护 #} <label for="i1"></label> <input id="i1" type="text" name="id" value="{{ student.id }}" style="display: none"> <label for="i2">学生姓名</label> <input id="i2" type="text" name="sname" value="{{ student.sname }}"> <label for="i3">所在班级</label> <select name="cid" id="i3"> {% for class in class_list %} {% if student.cid.id == class.id %} <option selected value="{{ class.id }}">{{ class.cname }}</option> {% else %} <option value="{{ class.id }}">{{ class.cname }}</option> {% endif %} {% endfor %} </select> <button type="submit">提交</button> <a href="{% url 'student_list' %}"><button type="submit">取消</button></a> </form> </body> </html>
为什么说cid为一个对象
Django把关系包装成一个具有的对象cid
表之间的关系
对应关系:
类 --> 表
类的属性 --> 字段
实例对象 --> 一条数据(数据行)
数据库层面
外键 对应 另外一个表的一条记录
cid_id
ORM层面:
外键 对应 另外一个表的一个对象
student_obj.cid_id ---> 具体的值
基于对象的跨表查询
一对多查询(班级表和学生表)
正向查询
(由学生表查询班级表) 按字段
查询学生的班级信息
>>> student_obj = models.Student.objects.first() >>> student_obj.cid # /通过model类中的属性查找到对应的外键数据对象 ---> <Class: linux4期> >>> student_obj.cid.cname ---> 'linux4期' >>> student_obj.cid_id # 获取实际外键的值 ---> 2
反向查询
(有班级表查询学生表) 表名_set
默认是表名_set.all()
如果在外键的字段中加了related_name属性,则按照该属性的来反向查找
>>> class_obj = models.Class.objects.first() # 获取第一个班级对象 >>> class_obj.student_set.all() # 通过表名_set反向查询出所有的学生 models.Class.objects.first().student_set.all() # 通过表名_set反向查询出所有的学生 --> <QuerySet [<Student: lishi>, <Student: dandan>, <Student: lili>]>
如果设置了related_name="students",反向查询时可直接使用students进行反向查询。
>>> models.Class.objects.first().students.all()
--><QuerySet [<Student: lishi>, <Student: dandan>, <Student: lili>]>
一对一查询
表结构设计
class Student(models.Model): id = models.AutoField(primary_key=True) sname = models.CharField(max_length=20) cid = models.ForeignKey(to="Class",to_field="id",related_name="students",null=True) # 表里面:student_obj.cid_id=Class对象.id ; student_obj.cid=Class对象 # related_name="students" 这个参数好处,表明我在class表的时候能够通过“students” 来找student的类 detail = models.OneToOneField("StudentDetail",null=True) def __str__(self): return self.sname # class StudentDetail(models.Model): height = models.PositiveSmallIntegerField() email = models.EmailField() memo = models.CharField(max_length=128,null=True)
正向查询
(由学生信息表查询学生详情表) 按字段
>>> student_obj = models.Student.objects.first() >>> student_obj.detail.email --- '11@55.com'
反向查询
(由学生详情表反向查询学生信息表) 按表名
>>> a = models.StudentDetail.objects.get(id=1) >>> a.student.sname ---- 'lishi'
总结
所有的反向的查询的表名均为小写,且需要提醒的是在一对一的反向查询中表名不需要跟set,因为它只有一个对象,通过“.表名”得到的是一个models对象,可以直接查询需要的字段。