18_多表练习
需求
- 学生注册
- 查看所有班级信息
- 显示某班学生情况
实现步骤
- 创建模型类(班级,学生,课程)
- 配置URL
- 创建视图函数
- 创建模板页面
INSTALLED_APPS = [
...
'django.contrib.staticfiles',
'stuapp',
]
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django20190909',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
demo6/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('student/', include('stuapp.urls')),
]
stuapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.register),
path('showall/', views.showall),
path('getstu/', views.getstu),
]
stuapp/models.py
from django.db import models
# Create your models here.
class Clazz(models.Model): # 班级模型
cno = models.AutoField(primary_key=True)
cname = models.CharField(max_length=30, unique=True)
def __str__(self):
return self.cname
class Course(models.Model): # 课程模型
courseid = models.AutoField(primary_key=True)
coursename = models.CharField(max_length=30)
def __str__(self):
return self.coursename
class Student(models.Model): # 学生模型
sno = models.AutoField(primary_key=True)
sname = models.CharField(max_length=30)
cls = models.ForeignKey(Clazz, on_delete=models.CASCADE, related_name="student")
course = models.ManyToManyField(Course)
def __str__(self):
return self.sname
# 将数据保存到数据库中的方法
def registerOper(sname, cname, *coursename):
try:
# 1.班级表插入操作
try:
cls = Clazz.objects.get(cname=cname)
except Clazz.DoesNotExist:
cls = Clazz.objects.create(cname=cname)
# 2.课程表插入操作
courseList = []
for cn in coursename:
couseObj = Course.objects.create(coursename=cn)
courseList.append(couseObj)
# 3.学生表插入操作
stu = Student.objects.create(sname=sname, cls=cls)
# 4.中间表插入操作
stu.course.add(*courseList)
return True
except Exception:
return False
stuapp/views.py
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from stuapp.models import registerOper, Clazz, Student
def register(request):
"""
1.注册页面的展示
2.处理注册功能
"""
if request.method == "GET":
return render(request, "register.html")
elif request.method == "POST":
# 1.获取请求参数
sname = request.POST.get('sname')
clazz = request.POST.get('clazz')
coursenames = request.POST.getlist('coursename')
# 2.将数据入库
flage = registerOper(sname, clazz, *coursenames)
# 3.处理页面响应
if flage:
return HttpResponse("注册成功!")
return HttpResponse('注册失败!')
else:
return HttpResponse("无法处理当前请求!")
def showall(request):
"""获取所有的班级信息"""
# 查询班级信息
claList = Clazz.objects.all()
return render(request, "show.html", {"claList": claList})
def getstu(request):
"""获取当恰班级下的学生详情信息"""
# 获取请求参数
cno = request.GET.get("cno", -1)
# 根据班级编号查询学生信息
# Clazz.objects.get(cno=cno).student.all()
# 还可以这样写
stuList = Student.objects.filter(cls_id=cno)
context = {"stuList": stuList}
return render(request, 'stuInfo.html', context)
templates/register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>register</title>
</head>
<body>
<form action="/student/" method="post">
{% csrf_token %}
<p>姓名:<input type="text" name="sname"></p>
<p>班级:
<select name="clazz">
<option value="B201_Python班">Python班</option>
<option value="B202_Java班">Java班</option>
<option value="B203_前端班">前端班</option>
<option value="B204_大数据班">大数据班</option>
</select>
</p>
<p>课程名称:
<input type="checkbox" name="coursename" value="HTML5">HTML5
<input type="checkbox" name="coursename" value="Java">Java
<input type="checkbox" name="coursename" value="Python">Python
<input type="checkbox" name="coursename" value="Spark">Spark
</p>
<p>   <input type="submit" value="注册"></p>
</form>
</body>
</html>
templates/show.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table border="1" cellspacing="0" width="500px">
<tr>
<th>编号</th>
<th>班级名称</th>
<th>操作</th>
</tr>
{% for cls in claList %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ cls.cname }}</td>
<td><a href="/student/getstu/?cno={{ cls.cno }}">详情</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>
templates/stuInfo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table border="1" cellspacing="0" width="500px">
<tr>
<th>编号</th>
<th>姓名</th>
<th>班级名称</th>
<th>课程名称</th>
</tr>
{% for stu in stuList %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ stu.sname }}</td>
<td>{{ stu.cls.cname }}</td>
<td>
{% for course in stu.course.all %}
{#   都是空格的意思 #}
{{ course.coursename }} 
{% endfor %}
</td>
</tr>
{% endfor %}
</table>
</body>
</html>
19_自定义Manager1
重写all()_get_queryset()
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.db.models.manager import Manager
class CustomManager(Manager):
#重写Student.objects.all()
# def all(self):
# return Manager.all(self).filter(isdelete=False)
def get_queryset(self):
return Manager.get_queryset(self).filter(isdelete=False)
class DeletedManager(models.Manager):
def get_queryset(self):
return Manager.get_queryset(self).filter(isdelete=True)
# Create your models here.
class Student(models.Model):
sname=models.CharField(max_length=30,unique=True)
isdelete=models.BooleanField(default=False)
objects=CustomManager()
delStus=DeletedManager()
class Meta:
db_table='t_student'
def __unicode__(self):
return u'Student:%s'%self.sname
20_自定义Manager2
重写删除
单个对象删除
- Student.objects.first().delete()
- Student.delete() #重写的是这个的父类delete()方法
批量删除
- Student.objects.filter().delete()
- Student.objects.filter().all() #重写_clone()方法
- Student.objects.all() #重写get_queryset()方法 查询所有记录
#Python3.6.7中写法
from django.db import models
import types
# Create your models here.
def delete1(self,delObjList):
for delObj in delObjList:
delObj.isdelete = True
delObj.save()
class CustomManager(models.Manager):
def filter(self,*args,**kwargs):
q = super(CustomManager, self).filter(*args,**kwargs)
# python3动态绑定实例方法
#动态给QuerySet类绑定的方法delete
q.delete = types.MethodType(delete1,q)
return q
调用:
from stuapp2.models import *
stuList = Student.objects.filter(isdelete=False)
stuList.delete(stuList)
#Python2.7中写法
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.db.models import QuerySet
from django.db.models.manager import Manager
class CustomManager(Manager):
#查询出需要删除的记录
def get_queryset(self):
row_queryset = Manager.get_queryset(self).filter(isdelete=False)
return row_queryset
#重写父类filter方法
def filter(self, *args, **kwargs):
#调用父类的filter方法
dellist = Manager.filter(self, *args, **kwargs)
#声明闭包方法进行逻辑删除
def delete1(delqueryset):
for delq in delqueryset:
delq.isdelete=True
delq.save()
import new
dellist.delete = new.instancemethod(delete1,dellist,QuerySet)
return dellist
Student.objects.filter().delete()
# Create your models here.
class Student(models.Model):
sname=models.CharField(max_length=30,unique=True)
isdelete=models.BooleanField(default=False)
objects=CustomManager()
# 重写Student.delete()
#实现单条记录的逻辑删除
# def delete(self, using=None, keep_parents=False):
# self.isdelete=True
# self.save()
class Meta:
db_table='t_student'
def __unicode__(self):
return u'Student:%s'%self.sname
闭包:
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
21_自定义Manager3
重写create()
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.db.models.manager import Manager
class CustomManager(Manager):
# 重写方法Student.objects.create()
# 实现Student.objects.create(sname='lisi',clazz='B208Python',course=('HTML5','UI','Java','Python'))
def create(self, **kwargs):
clsname=kwargs.get('clazz')
clazz = self.__get_cls(clsname)
kwargs['clazz']=clazz
course=kwargs.pop('course')
stu = Manager.create(self,**kwargs)
stu.save()
stu.course.add(*self.__get_course(*course))
return stu
def __get_cls(self, clsname):
try:
cls = Clazz.objects.get(cname=clsname)
except Clazz.DoesNotExist:
cls = Clazz.objects.create(cname=clsname)
return cls
def __get_course(self,*course):
row_course=[]
for cour in course:
try:
r_cour = Course.objects.get(course_name=cour)
except Course.DoesNotExist:
r_cour = Course.objects.create(course_name=cour)
row_course.append(r_cour)
return row_course
class Clazz(models.Model):
cname=models.CharField(max_length=30,unique=True)
class Meta:
db_table='t_clazz'
def __unicode__(self):
return u'Clazz:%s'%self.cname
class Course(models.Model):
course_name=models.CharField(max_length=30,unique=True)
class Meta:
db_table='t_course'
def __unicode__(self):
return u'Course:%s'%self.course_name
# Create your models here.
class Student(models.Model):
sname=models.CharField(max_length=30,unique=True)
clazz=models.ForeignKey(Clazz)
course=models.ManyToManyField(Course)
objects=CustomManager()
class Meta:
db_table='t_student'
def __unicode__(self):
return u'Student:%s'%self.sname