x学生管理系统(用中间件)-------基于FORM组件
目的:实现学生,老师,课程的增删改查
models.py
from django.db import models # Create your models here.
class UserInfo(models.Model):
"""
用户表:既有班主任也有老师
"""
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
email = models.CharField(max_length=32)
ut = models.ForeignKey(to="UserType") #用户和用户类型一对多的关系
teacher_classes = models.ManyToManyField(to="Classes") #老师和班级的多对多关系 class UserType(models.Model):
"""
用户类型表
"""
title = models.CharField(max_length=32) class Classes(models.Model):
"""
班级表
"""
name = models.CharField(max_length=32)
classteacher = models.ForeignKey(to="UserInfo") #班级和班主任是一对多的关系 class Student(models.Model):
"""
学生表
"""
name = models.CharField(max_length=32)
age = models.IntegerField(max_length=32)
cls = models.ForeignKey(to="Classes") #学生和班级的一对多关系
1、urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
#老师管理
url(r'^teacherindex/', views.teacherindex),
url(r'^addteacher/', views.addteacher),
url(r'^editteacher/(\d+)', views.editteacher),
url(r'^delteacher/(\d+)', views.delteacher),
#学生管理
url(r'^studentindex/', views.studentindex),
url(r'^addstudent/', views.addstudent),
url(r'^delstudent/(\d+)', views.delstudent),
url(r'^editstudent/(\d+)', views.editstudent), #班级管理
url(r'^classindex/', views.classindex),
url(r'^addclass/', views.addclass),
url(r'^delclass/(\d+)', views.delclass),
url(r'^editclass/(\d+)', views.editclass), #测试中间件
url(r'^test', views.testMD),
]
urls.py
2、views.py
from django.shortcuts import render,redirect,HttpResponse
from app01 import models
# Create your views here.
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from django.conf import settings
from django.core.validators import ValidationError
from django.core.validators import RegexValidator
# 1、创建规则
class TeacherForm(Form): #必须继承Form
# 创建字段,本质上是正则表达式
username = fields.CharField(
required=True, #必填字段
error_messages={"required":"用户名不能为空!!"}, #显示中文错误提示
widget=widgets.TextInput(attrs={"placeholder":"用户名","class":"form-control"}), #自动生成input框
label="姓名",
label_suffix=":"
)
password = fields.CharField(required=True, error_messages={'required': '密码不能为空'},
widget=widgets.PasswordInput(attrs={'placeholder': '密码', 'class': 'form-control'}),
label="密码",
label_suffix=":"
) # 不能为空 email = fields.EmailField(
required=True,
error_messages={"required":"邮箱不能为空!!","invalid":"无效的邮箱"},
widget=widgets.EmailInput(attrs={"placeholder": "邮箱", "class": "form-control"}), # 自动生成input框
label = "邮箱",
label_suffix = ":"
) #不能为空且邮箱格式要一致
teacher_classes = fields.MultipleChoiceField(
label="任教班级",
label_suffix=":",
choices=[] #注意一定要用values_list ) def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["teacher_classes"].choices = models.Classes.objects.values_list("id", "name") def clean_name(self):
name = self.cleaned_data["name"]
valid = models.Student.objects.filter(name=name).first()
if valid:
raise ValidationError("用户名已存在")
return name class LoginForm(Form):
username = fields.CharField(
required=True, #必填字段
min_length=3,
max_length=16,
error_messages={
"required":"用户名不能为空",
"min_length":"长度不能小于3",
"max_length":"长度不能大于16"
},
widget=widgets.TextInput({"placeholder":"username","class":"form-control"})
)
password = fields.CharField(
required=True,
min_length=3,
max_length=16,
error_messages={
"required": "密码不能为空",
"min_length": "密码长度不能小于3",
"max_length": "密码长度不能大于16",
# "invalid":"密码格式错误"
# error_messages的优先级高,如果写上"invalid":"密码格式错误"这个就会优先显示这个错误
},
widget=widgets.PasswordInput({"placeholder":"password","class":"form-control"}),
validators=[RegexValidator("\d+","密码只能是数字")] #可以进行正则匹配提示错误
) def clean_username(self):
user = self.cleaned_data["username"]
is_exits = models.UserInfo.objects.filter(username=user).count()
if not is_exits:
raise ValidationError("用户名和密码错误")
return user #必须有return class StudentForm(Form): #必须继承Form
# 创建字段,本质上是正则表达式 name = fields.CharField(
required=True, #必填字段
error_messages={"required":"姓名不能为空!!"}, #显示中文错误提示
widget=widgets.TextInput(attrs={"placeholder":"姓名","class":"form-control"}), #自动生成input框
)
age = fields.CharField(required=True, error_messages={'required': '年龄不能为空'},
widget=widgets.TextInput(attrs={'placeholder': '年龄', 'class': 'form-control'}),
) # 不能为空
class_list = models.Classes.objects.all().values_list('id',"name")
cls_id=fields.ChoiceField(choices=class_list)
# 这个方法判断用户名存在不
def clean_name(self):
name = self.cleaned_data["name"] #只能拿自己当前的字段值
valid = models.Student.objects.filter(name=name).first()
if valid:
raise ValidationError("用户名已存在") #主动报错
return name #必须有返回值 class ClassesForm(Form):
name = fields.CharField(
required=True, # 必填字段
error_messages={"required": "姓名不能为空!!"}, # 显示中文错误提示
widget=widgets.TextInput(attrs={"placeholder": "姓名", "class": "form-control"}), # 自动生成input框
)
# 如果直接定义成classteacher_id,,_id 的形式,这样你添加数据的时候不会时时更新,所以在下面定义一个重写的方法
# classteacher_id = fields.ChoiceField(choices= models.UserInfo.objects.filter(ut_id = settings.ROLE_CLASSTEACHER).values_list('id', "username")) classteacher_id = fields.ChoiceField(choices=[])
def __init__(self,*args,**kwargs): #重写init方法,时时更新
super().__init__(*args,**kwargs)
self.fields["classteacher_id"].choices = models.UserInfo.objects.filter(ut_id = settings.ROLE_CLASSTEACHER).values_list('id', "username") def login(request):
if request.method == "GET":
form = LoginForm()
return render(request, "login.html", {"form": form})
else:
form = LoginForm(data=request.POST)
if form.is_valid():
print(form.cleaned_data)
user = models.UserInfo.objects.filter(**form.cleaned_data).first()
if user: #这次是和数据库里的数据进行比较
#验证成功
print(user.username)
request.session[settings.GDP] = {"id":user.id,"username":user.username} #设置session
return redirect("/teacherindex/")
else:
#验证失败,就给增加一个错
form.add_error("password","用户名或密码不正确")
return render(request, "login.html", {"form": form})
else:
return render(request, "login.html", {"form": form}) # 用装饰器的方法实现验证,如果是正确的用户就可以进去主页并且操作,如果不是就进不去主页,还让在登录页面上
# 这个方法可以是可以,但是你的函数要是有成百上千个,那每个都加装饰器是不是就有点费事了。
# 那还有一种更牛逼的方法,那就是中间件。用中间件就可以实现和装饰器一样的功能了
def auth(func):
def inner(request, *args, **kwargs):
user_info = request.session.get("username")
if not user_info:
return redirect('/login/')
return func(request, *args, **kwargs)
return inner
#老师主页面 def teacherindex(request):
teacher_obj = models.UserInfo.objects.filter(ut_id=1)
username = request.session.get("username")
return render(request,"teacherindex.html",{"teacher_obj":teacher_obj,"username":username})
# 2、使用规则:将数据和规则进行匹配 def addteacher(request):
if request.method=="GET":
form = TeacherForm() #只是让显示一个input框
return render(request, "addteacher.html", {"form":form})
else:
form = TeacherForm(data=request.POST)
# print(form) #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
if form.is_valid():# 开始验证
cls_list = form.cleaned_data.pop("teacher_classes")
print("============id",cls_list)
form.cleaned_data['ut_id'] = 1
#创建新老师的对象
teacher_obj = models.UserInfo.objects.create(**form.cleaned_data)
#创建新老师和班级的关系
teacher_obj.teacher_classes.add(*cls_list) #以前添加的是对象,现在也可以吧id添加进去
return redirect("/teacherindex/")
else:
# print("=====?",form.errors,type(form.errors))#返回失败的结果
# print(form.errors["username"][0]) #拿到返回失败的结果,渲染到页面
return render(request, "addteacher.html", {"form":form}) def editteacher(request,nid):
obj = models.UserInfo.objects.filter(id=nid, ut_id=1).first()
# print(obj.username)
if not obj:
return redirect("/teacherindex/")
if request.method=="GET":
print([obj.id for obj in obj.teacher_classes.all()]) #[2] 拿到select框的id是为了要做默认显示的
form = TeacherForm(initial={"username":obj.username,"password":obj.password,"email":obj.email,"teacher_classes":[obj.id for obj in obj.teacher_classes.all()]}) #就让显示一个input框,并且带有原来哪一行的内容
return render(request, "editteacher.html", {"form":form})
else:
form = TeacherForm(data=request.POST)
if form.is_valid():#开始校验,注意这要加括号
cls_list = form.cleaned_data.pop("teacher_classes")
print(cls_list)
models.UserInfo.objects.filter(id=nid).update(**form.cleaned_data)
obj.teacher_classes.set(cls_list) #更新第三张表
return redirect("/teacherindex/")
else:
return render(request, "editteacher.html", {"form":form}) def delteacher(request,nid):
models.UserInfo.objects.filter(id=nid).delete()
return redirect("/teacherindex/") def studentindex(request):
username = request.session.get("username")
student_obj = models.Student.objects.all()
return render(request,"studentindex.html",{"student_obj":student_obj,"username":username}) def addstudent(request):
if request.method=="GET":
form = StudentForm()
return render(request,"addstudent.html",{"form":form})
else:
form = StudentForm(data=request.POST)
if form.is_valid():
print(form.cleaned_data)
models.Student.objects.create(**form.cleaned_data)
return redirect("/studentindex/")
else:
return render(request,"addstudent.html",{"form":form}) def delstudent(request,nid):
models.Student.objects.filter(id=nid).delete()
return redirect("/studentindex/") def editstudent(request,nid):
if request.method=="GET":
student_obj = models.Student.objects.filter(id=nid).first()
print(student_obj.cls_id)
if not student_obj:
return redirect("/studentindex/")
form = StudentForm(initial={"name":student_obj.name,"age":student_obj.age,"cls_id":student_obj.cls_id}) #这个name是设置的字段名
# form = StudentForm(initial=student_obj.values("name","age").first()) #显示input并且让带有你点击哪一行的数据
return render(request,"editstudent.html",{"form":form})
else:
form = StudentForm(data=request.POST)
if form.is_valid():
models.Student.objects.filter(id=nid).update(**form.cleaned_data)
return redirect("/studentindex/")
else:
return render(request,"editstudent.html",{"form":form}) def classindex(request):
class_obj = models.Classes.objects.all()
username = request.session.get("username")
return render(request,"classindex.html",{"class_obj":class_obj,"username":username}) def delclass(request,nid):
models.Classes.objects.filter(id=nid).delete()
return redirect("/classindex/") def addclass(request):
if request.method=="GET":
form = ClassesForm()
return render(request,"addclass.html",{"form":form})
else:
form = ClassesForm(data=request.POST)
if form.is_valid():
print(form.cleaned_data)
models.Classes.objects.create(**form.cleaned_data)
return redirect("/classindex/")
else:
return render(request,"addclass.html",{"form":form}) def editclass(request,nid):
if request.method == "GET":
class_obj = models.Classes.objects.filter(id=nid).first()
if not class_obj:
return redirect("/classindex/")
form = ClassesForm(initial={"name": class_obj.name,"classteacher_id":class_obj.classteacher_id}) # 这个name是设置的字段名,后面的那个做默认选中
# form = StudentForm(initial=student_obj.values("name","age").first()) #显示input并且让带有你点击哪一行的数据
return render(request, "editclass.html", {"form": form})
else:
form = ClassesForm(data=request.POST)
if form.is_valid():
models.Classes.objects.filter(id=nid).update(**form.cleaned_data)
return redirect("/classindex/")
else:
return render(request, "editclass.html", {"form": form}) def testMD(request):
print("view.test")
return HttpResponse("...")
Views.py
3、template
<!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">
<title>Title</title>
</head>
<body>
<form method="post" novalidate>
{% csrf_token %}
<p>用户名:{{ form.username }}{{ form.username.errors.0 }}</p>
<p>密码:{{ form.password }}{{ form.password.errors.0 }}</p>
<p>{{ s }}</p>
<p><input type="submit"></p>
</form>
</body>
</html>
login.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">
<title>Title</title>
<style>
.left{
width: 30%;
height: 400px;
position: relative;
}
.right{
width: 60%;
height: 400px;
position: absolute;
left: 300px;
top: 90px;
}
.c1{
margin-top: 100px;
}
</style>
</head>
<body>
<hr>
<div class="c1">
<div class="left">
<ul>
<li><a href="/teacherindex/">老师管理</a></li>
<li><a href="/studentindex/">学生管理</a></li>
<li><a href="/classindex/">班级管理</a></li>
</ul>
</div>
<div class="right">
{% block right %} {% endblock %}
</div>
</div>
</body>
</html>
base.html
{% extends "base.html" %}
{% block right %}
<h2>欢迎{{ username }}登录</h2>
<h3>学生信息管理</h3>
<hr>
<a href="/addstudent/"><button>添加学生</button></a>
<table border="">
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for s_obj in student_obj %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ s_obj.name }}</td>
<td>{{ s_obj.age }}</td>
<td>{{ s_obj.cls.name }}</td>
<td>
<a href="/editstudent/{{ s_obj.id }}"><button>编辑</button></a>
<a href="/delstudent/{{ s_obj.id }}"><button>删除</button></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
studentindex.html
{% extends "base.html" %}
{% block right %}
<h2>欢迎{{ username }}登录</h2>
<h3>老师信息管理</h3>
<hr>
<a href="/addteacher/"><button>添加老师</button></a>
<table border="">
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>邮箱</th>
<th>任教班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for t_obj in teacher_obj %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ t_obj.username }}</td>
<td>{{ t_obj.email }}</td>
{# <td>{{ t_obj.teacher_classes }}</td>#}
{# 多对多查关联字段#}
<td>
{% for foo in t_obj.teacher_classes.all %}
{{ foo.name }}
{% endfor %}
</td>
<td>
<a href="/editteacher/{{ t_obj.id }}"><button>编辑</button></a>
<a href="/delteacher/{{ t_obj.id }}"><button>删除</button></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
teacherindex.html
{% extends "base.html" %}
{% block right %}
<h2>欢迎{{ username }}登录</h2>
<h3>班级信息管理</h3>
<hr>
<a href="/addclass/"><button>添加班级</button></a>
<table border="">
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>班主任</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for c_obj in class_obj %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ c_obj.name }}</td>
<td>{{ c_obj.classteacher.username }}</td>
{# <td>{{ t_obj.ut.title }}</td>#}
<td>
<a href="/editclass/{{ c_obj.id }}"><button>编辑</button></a>
<a href="/delclass/{{ c_obj.id }}"><button>删除</button></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
classindex,html
{% extends "base.html" %}
{% block right %}
<form action="" method="post" novalidate>
{% csrf_token %}
<h1>添加学生信息</h1>
<hr>
<p>姓名:{{ form.name }}{{ form.name.errors.0 }}</p>
<p>年龄:{{ form.age }}{{ form.age.errors.0 }}</p>
<p>班级:{{ form.cls_id }}{{ form.cls_id.errors.0 }}</p>
<input type="submit">
</form>
{% endblock %}
addstudent.html
{% extends "base.html" %}
{% block right %}
<h1>添加老师信息</h1>
<hr>
<form method="post" novalidate>
{% csrf_token %}
{# <p>姓名:{{ form.username }}{{ form.errors.username.0 }}</p>#}
{# <p>密码:{{ form.password }}{{ form.errors.password.0 }}</p>#}
{# <p>邮箱:{{ form.email }}{{ form.errors.email.0 }}</p>#}
{# 也可以循环添加#}
{% for field in form %}
<p>{{ field.label_tag }}{{ field }}{{ field.errors.0 }}</p>
{% endfor %} <p><input type="submit" value="提交"></p>
</form>
{% endblock %}
addteacher.html
{% extends "base.html" %}
{% block right %}
<form action="" method="post" novalidate>
{% csrf_token %}
<h1>添加班级信息</h1>
<hr>
<p>班级:{{ form.name }}{{ form.age.errors.0 }}</p>
<p>班主任:{{ form.classteacher_id }}{{ form.classteacher_id.errors.0 }}</p>
<input type="submit">
</form>
{% endblock %}
addclass.html
{% extends "base.html" %}
{% block right %}
<form action="" method="post" novalidate>
{% csrf_token %}
<h1>修改学生信息</h1>
<hr>
<p>姓名:{{ form.name }}{{ form.name.errors.0 }}</p>
<p>年龄:{{ form.age }}{{ form.age.errors.0 }}</p>
<p>班级:{{ form.cls_id }}{{ form.cls_id.errors.0 }}</p>
<input type="submit">
</form>
{% endblock %}
editstudent
{% extends "base.html" %}
{% block right %}
<h1>修改老师信息</h1>
<hr>
<form method="post" novalidate>
{% csrf_token %}
{# {{ form.as_p}}#}
<p>姓名:{{ form.username }}{{ form.errors.username.0 }}</p>
<p>密码:{{ form.password }}{{ form.errors.password.0 }}</p>
<p>邮箱:{{ form.email }}{{ form.errors.email.0 }}</p>
<p>任教班级:{{ form.teacher_classes }}</p>
{# {% for field in form %}#}
{# <p>{{ field.label_tag }}{{ field }}{{ field.errors.0 }}</p>#}
{# {% endfor %}#}
<input type="submit" value="提交">
</form>
{% endblock %}
editteacher
{% extends "base.html" %}
{% block right %}
<form action="" method="post" novalidate>
{% csrf_token %}
<h1>修改班级信息</h1>
<hr>
<p>班级:{{ form.name }}{{ form.age.errors.0 }}</p>
<p>班主任:{{ form.classteacher_id }}{{ form.classteacher_id.errors.0 }}</p>
<input type="submit">
</form>
{% endblock %}
editclass
4、中间件
#!usr/bin/env python
# -*- coding:utf-8 -*-
# from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from django.shortcuts import redirect
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__() def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response # 至少要有两个类
class Md1(MiddlewareMixin): #必须继承
def process_request(self,request):
print("md1===process_request")
l = ["/login/"]
if request.path_info in l: #因为login不做验证,就直接返回none就行了
return None
if not request.session.get(settings.GDP):
return redirect("/login/")
#
# 如果无返回值,就继续执行后续中间件和视图函数
# 如果有返回值,就执行自己的process_response和上面的response
def process_response(self,request,response):
print("md1====process_response1")
return response #必须有返回值 class Md2(MiddlewareMixin):
def process_request(self,request):
print("md2====process_request2")
def process_response(self,request,response):
print("md2====process_response2")
return response
middlewear
5、settings
"""
Django settings for day75以及周末作业老师管理等 project. Generated by 'django-admin startproject' using Django 1.11.6. For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
""" import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'xi^$lfsye5x43af&)lpkx5l%^4%3$%qmx@5=+nrbwa^!b2aj)!' # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
] MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
#这是自定义的中间件
"middle.middle.Md1",
"middle.middle.Md2"
] ROOT_URLCONF = 'day75以及周末作业老师管理等.urls' TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
] WSGI_APPLICATION = 'day75以及周末作业老师管理等.wsgi.application' # Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
} # Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
] # Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/'
STATICFIELDS=[
os.path.join("/static/",BASE_DIR),
] # ============自定义配置文件===========
ROLE_TEACHER = 1
ROLE_CLASSTEACHER = 2
GDP="user_info"
settings
x学生管理系统(用中间件)-------基于FORM组件的更多相关文章
- 基于Form组件实现的增删改和基于ModelForm实现的增删改
一.ModelForm的介绍 ModelForm a. class Meta: model, # 对应Model的 fields=None, # 字段 exclude=None, # 排除字段 lab ...
- 图书管理系统 基于form组件
models: from django.db import models # Create your models here. class Book(models.Model): name = mod ...
- 2.1博客系统 |基于form组件和Ajax实现注册登录
基于forms组件和Ajax实现注册功能 1 基于forms组件设计注册页面 --点击头像 === 点击input --头像预览: 修改用户选中的文件对象:获取文件对象的路径:修改img的src属性, ...
- django上课笔记6-MVC,MTV架构-中间件-初识Form组件
一.MVC,MTV架构 models(数据库,模型) views(html模板) controllers(业务逻辑处理) --> MVC models(数据库,模型) templates(htm ...
- Django基于form组件实现注册校验
一 基本流程 1 创建form组件对应的类,比如LoginForm 2 前端的三种渲染方式: 渲染方式三种: 1 <form action="" novalidate met ...
- 基于FORM组件学生管理系统【中间件】
目的:实现学生,老师,课程的增删改查 models.py from django.db import models # Create your models here. class UserInfo( ...
- 图书管理系统(无中间件,用装饰器的)-----未基于FORM组件
目的:实现图书的增删改查 models.py from django.db import models # Create your models here. class Book(models.Mod ...
- day 77 基于form组件的注册功能
Form 表单 py文件 from django import forms #定义一个form类注册用 class RegForm (forms.Form): username =forms.Char ...
- django----基于Form组件实现的增删改和基于ModelForm实现的增删改
一.ModelForm的介绍 ModelForm a. class Meta: model, # 对应Model的 fields=None, # 字段 exclude=None, # 排除字段 lab ...
随机推荐
- 在webpack中区分环境变量
webpack 中的定义插件可以帮我们定义一些全局变量,使用方法如下: plugins: [ new webpack.DefinePlugin({ NODE_ENV: JSON.stringify(' ...
- python之读写文件
1. 读取文件数据,文件必须存在才可以读且如要读取的文件不和当前.py在同一个包下,需要特别指定此文件路径才行 f=open('test.txt',encoding='utf-8')#填写文件路径,打 ...
- 批量清除react中的计时器小组件
在Timers的父组件被卸载时,批量清除各个计时器.
- redis-deskmanager 连不上 虚拟机 - centos redis
1.没设置redis密码 : https://blog.csdn.net/HUXU981598436/article/details/54668779 2.关闭防火墙
- mysql案例~mysql主从复制延迟概总
浅谈mysql主从复制延迟 1 概念解读 需要知道以下几点 1 mysql的主从同步上是异步复制,从库是串行化执行 2 mysql 5.7的并行复制能加速从库重做的速度,进一步缓解 主从同步的延迟问题 ...
- Aizu 2170 Marked Ancestor
题意:出一颗树,有两种操作:1. mark u 标记结点u2.query u 询问离u最近的且被标记的祖先结点是哪个让你输出所有询问的和. 思路:数据量太小,直接暴力dfs就可以了 #incl ...
- delete 和 delete []的区别
(1). 针对简单类型 使用new分配后的不管是数组还是非数组形式内存空间用两种方式均可 如: int *a = new int[10]; delete a; delete [] a; ...
- C&C++动态分配内存(手动分配内存)三种方式
1. malloc函数 函数原型:void *malloc(unsigned int size)函数的作用是:在内训的动态存储区开辟一个size个字节的连续空间,返回所分配区域的首字节地址. 可以看到 ...
- SQLServer常用分页方式
mysql的分页是基于limit关键字,oracle的分页是基于rownum行号,SQLserver的分页在下面进行研究,是基于SQLServer2012进行的测试. 0.原来的SQL的所有数据 下面 ...
- linux 制作U盘启动,和定制系统
找到u盘的路径 fdisk -l 将镜像写入u盘 dd if=/root/Downloads/kali-linux-2017.1-amd64.iso of=/dev/sdc 定制U盘启动系统: 安装完 ...