django1.11琐碎知识点
1.QueryDict对象
request.POST或request.GET
获取的对象类型为QueryDict,默认是不可变数据类型,可以通过copy.deepcopy(QueryDict)方式来使它变成可变的数据类型,或者直接QueryDict.copy()
官网地址
2.urlencode() 查询参数拼接
http://127.0.0.1:8000/customer/search/?page=2&condition=qq&keyword=199
request.GET
<QueryDict: {'page': ['2'], 'condition': ['qq'], 'keyword': ['199']}>
request.GET.urlencode()
page=2&condition=qq&keyword=199
3.modelformset的使用
forms.py 表单认证文件
from django import forms
class StudyRecordModeForm(forms.ModelForm):
class Meta:
model = models.StudentStudyRecord
fields = ["score", "homework_note"] # 注意只写需要验证的字段
def clean_score(self):
val = self.cleaned_data.get("score")
if val > 0:
raise ValidationError("分数大于0")
else:
return val
urls.py 路由文件
classrecordurl = [
url(r'^study/(\d+)/$', views.StudyRecord.as_view(), name="studyrecord"),
]
urlpatterns = [
url(r'^classrecord/', include(classrecordurl)), # 跟进记录总路由
]
views.py 视图函数
from django.forms.models import modelformset_factory
class StudyRecord(View):
def get(self, request, pk):
queryset_modelform = modelformset_factory(
model=models.StudentStudyRecord, # 指定需要操作的表 必填
form=modelform.StudyRecordModeForm, # 指定表单验证类 必填
extra=0) # 默认1 会在额外生成1条空数据,用于添加 可选参数
# queryset_modelform 是一个类名
all_students = models.StudentStudyRecord.objects.filter(classstudyrecord_id=pk)
querysets = queryset_modelform(queryset=all_students) # 实例化一个类 queryset指定对哪些数据进行操作
return render(request, "studyrecord.html", {"querysets": querysets})
def post(self, request, pk):
queryset_modelform = modelformset_factory(
model=models.StudentStudyRecord,
form=modelform.StudyRecordModeForm
)
querysets = queryset_modelform(request.POST)
if querysets.is_valid():
querysets.save()
return self.get(request, pk)
else:
print(querysets.errors) # [{'score': ['分数大于0']}, {'score': ['分数大于0']}, {}, {}, {}] 按顺序依次打印出来
return render(request, "studyrecord.html", {"querysets": querysets}) # 不会把报错信息渲染到页面,需要自己手动渲染
studyrecord.html 渲染页面
<form action="" method="post">
<table class="table table-bordered table-hover dataTable" aria-describedby="example2_info">
<thead>
<tr role="row">
<th>序号</th>
<th>学生</th>
<th>上课纪录</th>
<th>本节成绩</th>
<th>作业评语</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% csrf_token %}
{{ querysets.management_form }} # 这个必须要写
{% for foo in querysets %}
{{ foo.id }} # 这个必须要写
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ foo.instance.student }}</td> # instance 实例化的学生 不能编辑
<td>{{ foo.instance.get_record_display }}</td>
<td>{{ foo.score }}</td> # 没有实例化 可以编辑 注意和forms.py里的验证类对应
<td>{{ foo.homework_note }}</td>
<td>
<a href="" class="btn btn-warning">编辑</a>
<a href="" class="btn btn-danger">删除</a>
</td>
</tr>
{% endfor %}
</table>
<button class="btn btn-primary pull-right">保存</button>
</form>
html页面
官网地址
4.Q查询
from django.db.models import Q
def search(request):
keyword = request.GET.get("keyword", "")
condition = request.GET.get("condition", "")
q = Q()
q.children.append((condition + "__contains", keyword)) # 可以把变量变成查询语句
customers = models.Customer.objects.filter(q).order_by("-pk")
5.get_user_model 获取用户表
from django.contrib.auth import get_user_model
User = get_user_model()
6.AUTHENTICATION_BACKENDS
指定认证后端
Django维护一个”authentication backends”的列表用来测试认证。当调用 django.contrib.auth.authenticate() — Django将尝试所有的认证后端。如果第一个认证方法失败了,Django将会继续尝试第二个,直到所有的都被尝试过。
认证后端的列表在 AUTHENTICATION_BACKENDS 设置。内容应该是包含Python路径的元组。默认情况下, AUTHENTICATION_BACKENDS 设置为
(‘django.contrib.auth.backends.ModelBackend’,),这是检测Django用户数据库的基本认证方案。
按照 AUTHENTICATION_BACKENDS 的排列顺序,如果同样的用户名和密码在第一次就匹配了,那么Django将停止处理后面的东西。
编写一个认证后端
一个认证后端是一个类,实现了2个方法:get_user(id) 和 authenticate(**credentials) 。
get_user 方法接受一个 id (可以是用户名,数据库ID或者其他的什么)并且返回一个 User 对象。
authenticate 方法接受字典型认证信息的参数。大多情况下是如下样子的
class MyBackend:
def authenticate(username=None, password=None):
# 检测用户名和密码,并返回一个User。
他也可以处理一个代号(token),像这样
class MyBackend:
def authenticate(token=None):
# 检测并返回User。
当 authenticate 接受的参数被验证为有效的时候,应该返回一个 User 对象;如果无效的时候,应该返回 None 。
Django的admin系统紧密地与 User 对象绑定在一起。目前,最好的处理方法就是为你每一个现存的后端(例如,你的LDAP目录或者你的外部SQL数据库等等。)数据创建一个Django的 User 对象。你可以预先写一个脚本来做这些事情,或者在用户第一次登录的时候在你的 authenticate 方法中做这些事情。
下面是一个例子,使用在 settings.py 文件里定义的用户名和密码并且在用户第一次登录的时候创建一个Django的 User 对象。
from django.conf import settings
from django.contrib.auth.models import check_password
from django.contrib.auth import get_user_model
User = get_user_model()
class SettingsBackend:
"""
Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.
Use the login name, and a hash of the password. For example:
ADMIN_LOGIN = ‘admin’
ADMIN_PASSWORD = ‘sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de’
"""
def authenticate(self, username=None, password=None, **kwargs):
try:
user = User.objects.get(Q(username=username)|Q(mobile=username))
if user.check_password(password):
return user
except Exception as e:
return