- admin 中,展示带有 choices 属性的字段时 Django 会自动帮我们调用 get status display 方法 所以不用配置
models.py
STATUS_ITEMS = [
(0, '申请'),
(1, '通过'),
(2, '拒绝'),
]
status = models.IntegerField(choices=STATUS_ITEMS, default=0, verbose_name='审核状态')
views.py
def index(request):
students = Student.objects.all()
return render(request,'student/index.html',context={'students':students})
index.html
<ul>
{% for student in students %}
<li>{{ student.name }} - {{ student.get_status_display }}</li>
{% endfor %}
</ul>
一 定义表单
在应用student目录下新建forms.py文件,编写代码
from django import forms
from .models import Student
class StudentForm(forms.ModelForm):
# clean_qq就是Form自动调用来处理每个字段的方法方法
# 检验qq是否输入合法
def clean_qq(self):
cleaned_data = self.cleaned_data['qq']
if not cleaned_data.isdigit():
raise forms.ValidationError('必须是数字!')
return int(cleaned_data)
class Meta:
model = Student
fields = (
'name', 'sex', 'profession', 'email', 'qq', 'phone'
)
其中clean_XX方法可以对数据进行检验
views.py
from .forms import StudentForm
from django.http import HttpResponseRedirect
def index(request):
students = Student.objects.all()
if request.method == 'POST':
form = StudentForm(request.POST)
if form.is_valid():
form.save()
# reverse方法,在student/urls.py中定义index时候,声明了name = 'index'
# 可以通过reverse拿到对应的url
return HttpResponseRedirect(reverse('index'))
else:
form = StudentForm
context = {
'students':students,
'form':form
}
return render(request,'student/index.html',context=context)
index.html
<form action="/" method="post">
{# csrf_token 是django对提交的数据安全性做校验 #}
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit"/>
</form>
二 优化数据获取逻辑
在models.py中我们定义模型类,要想获取数据库所有数据在views.py使用:
students = Student.objects.all()
在 view 函数中通过 students = Student . objects.all ()的方式 取到了所有学员 的数据,但是这种方式在实际使用中会有 因为后期可能会对学员的数据 进行过滤,比如需要调整为展示所有审核通过的学员, 此时就需要调整 view 函数中的代码 者对结果进行缓存,也需要调整代码
因此,可以把数据获取逻辑封装到model层中,同时修改views.py
未修改
models.py:
class Student(models.Model):
# 其他代码
views.py
def index(request):
students = Student.objects.all()
# 其它代码
修改后:
models.py
class Student(models.Model):
# 其它代码
@classmethod
def get_all(cls):
return cls.objects.all()
增加get_all方法
views.py
def index(request):
students = Student.get_all()
三 TestCase
测试数据库
在Django 中运行测试用例时,如 我们用的是 SQLite 据库, ango 会帮我们创建一个 基于内存的测试数据库,用于测试
但是对于MySQL数据库,django会直接用配置数据库用户名和密码创建一个名为 test_student_db 的数据库,用户测试,因此,需要保证有建表和建库的权限,你也可以定义测试数据库的名称,在settings.py中配置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'graduation', #数据库名称
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '3306',
'TEST': {
'NAME': 'mytestdatabase', # 这里配置
},
}
}
Django提供一个名为TestCase的基类,有以下方法:
- def setUp(self) - 如其名,用来初始化环境,包括创建初始化的数据,或者做一些其他的准备的工作。
- def testxxxx(self) - 方法后面的xxxx可以是任意的东西,以test开头的方法,会被认为是需要测试的方法,跑测试时会被执行。每个需要被测试的方法是相互独立的。
- def tearDown(self) - 跟setUp相对,用来清理测试环境和测试数据。在Django中,我们可以不关心这个。
Model 层测试
这一层的测试,主要是来保证数据的写入和查询是可用的,同时也需要保证我们在Model层所提供的方法是符合预期的。
student/tests.py
from django.test import TestCase, Client
from .models import Student
class StudentTestCase(TestCase):
def setUp(self):
Student.objects.create(
name='test',
sex=1,
email='test@qq.com',
qq='333333',
phone='1111'
)
在setup方法中创建一条测试数据,用于测试数据库创建数据
View 层测试
这一层更多的是功能上的测试,也是我们一定要写的,功能上的可用是比什么都重要的事情。当然这事你可以通过手动浏览器访问来测试,但是如果你有几百个页面呢?
这部分的测试逻辑依赖Django提供的Django.test.Client对象。在上面的文件中tests.py中,我们增加下面两个函数:
def test_post_student(self):
client = Client()
data = dict(
name = 'test_post',
sex=1,
email='test@163.com',
profession='程序员',
qq='333',
phone='3222',
)
response = client.post('/',data)
self.assertEqual(response.status_code,302,'status code must 302')
四 QuerySet
QuerySet本质上是一个懒加载对象,都不会产生数据库查询操作,只是会返回一个 Query Set 对象,等你真正用它时才会执行查询
常用的queryset接口
进阶接口
常用字段查询
进阶查询
以上资料可以查询:
- queryset api
- Django 数据库访问优化
- 查询条件语句
- 聚合查询
五 admin页面查看操作日志
在应用文件夹下的admin.py
from django.contrib import admin
from django.contrib.admin.models import LogEntry
@admin.register(LogEntry)
class LogEntryAdmin(admin.ModelAdmin):
list_display = ['object_repr','object_id','action_flag','user','change_message']