Web框架之Django【基础篇】-基本配置 路由系统 模板 自定义函数 中间件 admin Views django基于中间件的IP访问频率控制

Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。

Python的其他WEB框架

Python web框架之Tornado

tornado的ORM

Web框架的引入

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author:Uson
 4 
 5 import socket
 6 
 7 def handle_request(client):
 8     buf = client.recv(1024)
 9     client.send(b"HTTP/1.1 200 OK\r\n\r\n")
10     client.send(b"Hello, Seven")
11 
12 def main():
13     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
14     sock.bind(('localhost', 8000))
15     sock.listen(5)
16 
17     while True:
18         connection, address = sock.accept()
19         handle_request(connection)
20         connection.close()
21 
22 if __name__ == '__main__':
23     main()
24     # http://127.0.0.1:8000/测试
base1
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author:Uson
 4 
 5 from wsgiref.simple_server import make_server
 6 
 7 def index():
 8     # return 'index'
 9     f = open('../Template/index.html')
10     data = f.read()
11     return data
12 
13 def login():
14     # return 'login'
15     f = open('../Template/login.html')
16     data = f.read()
17     return data
18 
19 def routers():
20     urlpatterns = (
21         ('/index/', index),
22         ('/login/', login),
23     )
24     return urlpatterns
25 
26 def run_server(environ, start_response):
27     # environ   客户端发来的所有数据
28     # start_response    封装要返回给用户的数据,包含响应头的状态
29     start_response('200 OK', [('Content-Type', 'text/html')])
30 
31     # return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ]
32     # 有病:有时必须列表,有时列表不行,必须字符串,真有病
33     # return ["<h1>Hello Web!</h1>".encode("utf-8")]
34 
35     url = environ['PATH_INFO'] # /uson/
36 
37     url = url + '/'
38 
39     urlpatterns = routers()
40     func = None
41     for item in urlpatterns: #循环这个元组
42         if item[0] == url:  #item[0] = '/index/'
43             func = item[1]  #func = index
44             break
45     if func: #如果index函数存在
46         return [func().encode("utf-8")] #执行index函数,并返回执行结果
47         # 1、转二进制; 2、返回列表形式 3、url + '/'
48 
49     else:
50         # self.status.split(' ',1)[0], self.bytes_sent
51         # AttributeError: 'NoneType' object has no attribute 'split'
52         # return b'404 not found'
53         return [b'404 not found']  # 必须是列表
54 
55 
56 if __name__ == '__main__':
57     httpd = make_server('', 8000, run_server)
58     print("Serving HTTP on port 8000...")
59     httpd.serve_forever()
60 
61     # 断点判断start_response
62     # 进入debug模式
63     # 浏览器输入:http://127.0.0.1:8000/uson测试
64     # 'PATH_INFO'(58335824) = /uson
base2
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author:Uson
 4 from wsgiref.simple_server import make_server
 5 from jinja2 import Template
 6 
 7 def index():
 8     # return 'index'
 9     # template = Template('Hello {{ name }}!')
10     # result = template.render(name='John Doe')
11 
12     f = open('../Template/index2.html')
13     result = f.read()
14     template = Template(result)
15     data = template.render(name='John Doe', user_list=['alex', 'eric'])
16     return data.encode('utf-8')
17 
18 def login():
19     # return 'login'
20     f = open('login.html')
21     data = f.read()
22     return data
23 
24 def routers():
25     urlpatterns = (
26         ('/index/', index),
27         ('/login/', login),
28     )
29     return urlpatterns
30 
31 def run_server(environ, start_response):
32     start_response('200 OK', [('Content-Type', 'text/html')])
33     url = environ['PATH_INFO']
34     urlpatterns = routers()
35     func = None
36     for item in urlpatterns:
37         if item[0] == url:
38             func = item[1]
39             break
40     if func:
41         return func()
42     else:
43         return [b'404 not found']
44 
45 if __name__ == '__main__':
46     httpd = make_server('', 8000, run_server)
47     print("Serving HTTP on port 8000...")
48     httpd.serve_forever()
实例

Django路由原理

基本配置

一、创建django程序

  • 终端命令:django-admin startproject sitename
  • IDE创建Django程序时,本质上都是自动执行上述命令

其他常用命令:

  python manage.py runserver 0.0.0.0   运行Django程序
  python manage.py startapp appname   创建app
  python manage.py syncdb    Django1.7版本后取消了

  根据类自动创建数据库表
  python manage.py makemigrations
  python manage.py migrate

  创建 Django 用户

  python manage.py createsuperuser

二、程序目录

三、配置文件

1、数据库

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'dbname',
    'USER': 'root',
    'PASSWORD': 'xxx',
    'HOST': '',
    'PORT': '',
    }
}
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
  
# 如下设置放置的与project同名的配置的 __init__.py文件中
  
import pymysql
pymysql.install_as_MySQLdb() 

2、模版

TEMPLATE_DIRS = (
        os.path.join(BASE_DIR,'templates'),
    )

3、静态文件

STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'static'),
    )

路由系统

形式:

from django.conf.urls import url   
from django.urls import path, re_path   第二种方式正则匹配只能用re_path

1、单一路由对应

url(r'^index$', views.index), FBV    r:防止转义;url最好加上终止符$,否则永远只匹配前缀。
url(r'^home/', views.Home.as_view()), CBV

2、基于正则的路由

url(r'^index/(\d*)', views.index),
url(r'^manage/(?P<name>\w*)/(?P<id>\d*)', views.manage),
\d+  \w+ 等同于 \d*  \w*

3、添加额外的参数

url(r'^manage/(?P<name>\w*)', views.manage,{'id':333}),

4、为路由映射设置名称

对URL路由关系进行命名, ***** 以后可以根据此名称生成自己想要的URL *****

url(r'^home', views.home, name='h1'), ==>模板中(action)使用生成URL {% url 'h1' %}
url(r'^index/(\d*)', views.index, name='h2'),   ==>模板中(action)使用生成URL {% url 'h2' 任意数字 %} ==>name='h2'只匹配前缀/  (模板任意数字个数要与url对应

设置名称之后,可以在不同的地方调用,如:

url(r'^asdfasdfasdf/', views.index, name='i1'),
url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'),
url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),

def func(request, *args, **kwargs):
	from django.urls import reverse
	
	url1 = reverse('i1')                              # asdfasdfasdf/
	url2 = reverse('i2', args=(1,2,))                 # yug/1/2/
	url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/

xxx.html
	
	{% url "i1" %}               # asdfasdfasdf/
	{% url "i2" 1 2 %}           # yug/1/2/
	{% url "i3" pid=1 nid=9 %}   # buy/1/9/

注:
	# 当前的URL
	request.path_info 
模板中使用生成URL     {% url 'h2' 2012 %}  ===> 可以不用任意数字,让提交的url与当前url相同:{{request.path_info}}  任意数字适用于指定跳转
函数中使用生成URL     reverse('h2', args=(2012,2019,)) / reverse('h2', kwargs=({'nid':1, 'uid':2})) 路径:from django.urls import reverse  生成新的url {% url 'h1' 2012 2019 %}/ {% url 'h1' nid=1 uid=2 %}
Model中使用获取URL  自定义get_absolute_url() 方法
class NewType(models.Model):
    caption = models.CharField(max_length=16)


    def get_absolute_url(self):
        """
        为每个对象生成一个URL
        应用:在对象列表中生成查看详细的URL,使用此方法即可!!!
        :return:
        """
        # return '/%s/%s' % (self._meta.db_table, self.id)
        # 或
        from django.urls import reverse
        return reverse('NewType.Detail', kwargs={'nid': self.id})

获取请求匹配成功的URL信息:request.resolver_match

# ResolverMatch:
ResolverMatch(func=app03.views.index, args=(), kwargs={}, url_name=None, app_names=['app03'], namespaces=['c-auth'], route=cohui/index$)

5、根据app对路由规则进行分类

url(r'^monitor/',include('app01.urls')),  一级路由   对应app下urls:二级路由

6、命名空间(用于reverse生成url)

a. project.urls.py

from django.conf.urls import url,include
 
urlpatterns = [
    url(r'^a/', include('app01.urls', namespace='author-polls')),
    url(r'^b/', include('app01.urls', namespace='publisher-polls')),
]

b. app01.urls.py

from django.conf.urls import url
from app01 import views
 
app_name = 'app01'
urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]

c. app01.views.py

def detail(request, pk):    # from django.urls import reverse
    print(request.resolver_match)
    return HttpResponse(pk)

以上定义带命名空间的url之后,使用name生成URL时候,应该如下:

  • v = reverse('author-polls:detail', kwargs={'pk':11})
  • {% url 'author-polls:detail' pk=12 %}

django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

通过反射机制,为django开发一套动态的路由系统Demo:点击下载

模板

1、模版的执行

模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
from django import template
t = template.Template('My name is {{ name }}.')
c = template.Context({'name': 'Adrian'})
print t.render(c)
import datetime
from django import template
import DjangoDemo.settings
 
now = datetime.datetime.now()
fp = open(settings.BASE_DIR+'/templates/Home/Index.html')
t = template.Template(fp.read())
fp.close()
html = t.render(template.Context({'current_date': now}))
return HttpResponse(html)
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime
 
def current_datetime(request):
    now = datetime.datetime.now()
    t = get_template('current_datetime.html')
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)
return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))

2、模版语言

 模板中也有自己的语言,该语言可以实现数据展示

  • {{ item }}
  • {% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}
      forloop.counter
      forloop.first
      forloop.last 
  • {% if ordered_warranty %}  {% else %} {% endif %}
  • 母板:{% block title %}{% endblock %}   母版中block块内,不能使用 if 判断语句,会失效
    子板:{% extends "base.html" %}           extends 母板文件名  :一个页面只能继承一个母版,放在页面最顶部位置;include组件可以有多个
       {% block title %}{% endblock %}   block块的顺序无关
  • 帮助方法:
    {{ item.event_start|date:"Y-m-d H:i:s"}}
    {{ bio|truncatewords:"30" }}
    {{ my_list|first|upper }}
    {{ name|lower }}

3、自定义函数:

1)simple_tag

a、在app中创建templatetags目录(不能改名)

b、该目录下创建任意 .py 文件,如:xxoo.py

c、创建template对象register(不能改名)

d、示例:

#!/usr/bin/env python
#coding:utf-8
from django import template # 1)
from django.utils.safestring import mark_safe
   
register = template.Library()  # 2)
   
@register.simple_tag  # 3)
def my_simple_time(v1,v2,v3):
    return  v1 + v2 + v3
   
@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

e、在使用自定义simple_tag的html文件中导入之前创建的 xxoo.py 文件名

顶部添加(extends下面):
{% load xxoo %}

f、使用simple_tag({% 函数名 arg1 arg2 %})使用时,空格个数无关

{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}

g、在settings中配置当前app,不然django无法找到自定义的simple_tag

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',
)

更多见文档:https://docs.djangoproject.com/en/1.10/ref/templates/language/

缺点:不能作为if条件

优点:可以任意参数,没有太多的限制,所以simple

2)filter

a、在app中创建templatetags目录(不能改名)

b、该目录下创建任意 .py 文件,如:xxoo.py

c、创建template对象register(不能改名)

d、示例:同例

e、在使用自定义filter的html文件中导入之前创建的 xxoo.py 文件名

f、使用filter({{ arg1|函数名:数字 }}或{{ arg1|函数名:"arg2,arg3" }})使用时,不能有空格

g、在settings中配置当前app,不然django无法找到自定义的filter

缺点:最多两个参数,且不能有空格

优点:可以作为if条件使用

实例:

templatetags.xxoo.py:

from django import template
register = template.Library()
@register.simple_tag  #  @register.filter
def uson(n1, n2):
    return n1 + n2

views:

# 自定义函数 - simple_tag
def tpl3(request):
    user_list = ['uson', 'cohui', 'zhou', 'han']
    return render(request, 'tpl3.html', {'user_list': user_list})

tpl3:

{% extends 'master.html' %}

<!-- 自定义函数导入 -->
{% load xxoo %}

{% block content1 %}
    <!-- 自定义函数simple_tag调用 -->
    页面分页 {% uson 10 50 %}   

    <!-- 自定义函数filter调用 -->
    页面分页 {{ 10|uson:50 }}       
{% endblock %}

中间件

django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图。

与mange.py在同一目录下的文件夹 uson/middleware下的mi.py文件中的M1类:

中间件中可以定义四个方法,分别是:

  • process_request(self,request)
  • process_view(self, request, callback, callback_args, callback_kwargs)
  • process_response(self, request, response)
  • process_exception(self, request, exception)         # views函数出现异常就会执行
  • process_template_response(self,request,response)    # 若views中函数的返回对象中,具有render方法就会执行,无什么卵用,参考下面的小实例

以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。

自定义中间件

1、创建中间件类

class M1(object):
      
    def process_request(self,request):
        pass
    def process_view(self, request, callback, callback_args, callback_kwargs):
        i =1
        pass
    def process_exception(self, request, exception):
        pass
      
    def process_response(self, request, response):
        return response

2、注册中间件

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'uson.middleware.m1.M1',
)

小实例

urls:

##########################################自定义中间件###############################
    # url(r'^test$', views.test), #http://127.0.0.1:8008/cohui/test2-1报错
    url(r'^test', views.test), #http://127.0.0.1:8008/cohui/test2-1正常显示

#################################process_template_response##################################
    url(r'^test2-(\d+)', views.test2),

views函数

##########################################自定义中间件###############################
# (1)找到模仿:
from django.middleware.csrf import CsrfViewMiddleware
# (2)CsrfViewMiddleware(MiddlewareMixin)
#     继承from django.utils.deprecation import MiddlewareMixin类
# (3)新建文件夹middle/m1.py
# (4)加入MIDDLEWARE = {}
# (5)写个url、view测试
def test(request):
    print("小姨妈没带钱。")
    return HttpResponse('OK')

###############################process_template_response#####################################
class Foo(object):
    def render(self):
        return HttpResponse('uson没带钱')

def test2(request, nid):
    # nid = int('uson') #异常处理
    print("uson没带钱。")
    return Foo()

注册中间件:

# 自定义中间件
'uson.middle.m1.M1',
'uson.middle.m1.M2',
'uson.middle.m1.M3',

自定义中间件:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Uson

from django.utils.deprecation import MiddlewareMixin

# 顺序:uson-->cohui-->fang    -->zhi-->qiang-->zhoubo
# uson      zhoubo
# cohui     qiang
# fang      zhi

class M1(MiddlewareMixin):
    def process_request(self, request):
        print("uson")

    def process_view(self, request, view_func, view_func_args, view_func_kwargs):
        # view_func_args:    传参到url(r'^test2-(\d+)', views.test2)
        # view_func_kwargs    传参到url(r'^test2-(?P<nid>\d+)', views.test2)
        print("USON大写")

    def process_response(self, request, response): #注意参数的顺序
        print("zhoubo")
        return response

class M2(MiddlewareMixin):
    def process_request(self, request):
        print("cohui")
        # from django.shortcuts import HttpResponse
        # return HttpResponse('返回去')

    def process_view(self, request, view_func, view_func_args, view_func_kwargs):
        # view_func_args:    传参到url(r'^test2-(\d+)', views.test2)
        # view_func_kwargs    传参到url(r'^test2-(?P<nid>\d+)', views.test2)
        print("COHUI大写")

    def process_response(self, request, response):  # 注意参数的顺序
        print("qiang")
        return response

class M3(MiddlewareMixin):
    def process_request(self, request):
        print("fang")

    def process_view(self, request, view_func, view_func_args, view_func_kwargs):
        # view_func_args:    传参到url(r'^test2-(\d+)', views.test2)
        # view_func_kwargs    传参到url(r'^test2-(?P<nid>\d+)', views.test2)
        print("USON-COHUI大写")

    def process_response(self, request, response): #注意参数的顺序
        print("zhi")
        return response

    def process_exception(self, request, exception):
        # 当view函数出现异常时,才会执行该方法
        print("exception: ", exception) # 打印view的异常信息
        # exception:  invalid literal for int() with base 10: 'uson'

        # 处理异常
        print(exception, ValueError)  # 判断一个对象是否是一个已知的类型
        # "exception":invalid literal for int() with base 10: 'uson' 
        # "ValueError":<class 'ValueError'>

        if isinstance(exception, ValueError):  # True
            from django.shortcuts import HttpResponse
            return HttpResponse('出现异常了')

    def process_template_response(self, request, response):
        # 当Views中的函数返回的对象中,具有render方法,就会执行该函数
        # 例如:return render()
        # 也可以通过 以下方式操作
        print("改造Views函数调用方法实现了")

        from django.shortcuts import HttpResponse
        # return HttpResponse('改造Views函数调用方法实现了')  #  X
        # 'HttpResponse' object has no attribute 'render'

        return response                                   #  √

Django请求的整个生命周期

1、用户请求过来,先到达Django的中间件:

2、先执行process_request函数:

当process_request有return HttpResponse('返回去'),就不再往下执行,而是先执行同一个中间件的process_response函数一步一步返回;

当process_request没有return,会执行完全部中间件的process_request函数,到达路由映射系统,进行url正则匹配;如果匹配成功,就折回去执行每个中间件的process_view函数;如果匹配失败,也是执行process_response函数一步一步返回;

3、折回去执行每个中间件的process_view函数

如果process_view函数有return,则不往下执行,而是从最后一个中间件的process_response函数开始执行,并一步一步返回

如果process_view函数执行完毕,就会到达Views视图函数,从数据库获取数据和模板文件,通过模板语言进行渲染;

如果Views视图函数处理出现异常,就会把异常信息返回到process_exception函数中,如果异常处理了,就会跳到最后一个中间件的process_response函数,依次返回给用户;

如果异常未得到处理,会返回直到第一个中间件,最终程序报错。

4、最后执行process_response函数,把数据一步一步返回给用户。

django基于中间件的IP访问频率控制

admin的配置

admin是django强大功能之一,它能共从数据库中读取数据,呈现在页面中,进行管理。默认情况下,它的功能已经非常强大,如果你不需要复杂的功能,它已经够用,但是有时候,一些特殊的功能还需要定制,比如搜索功能,下面这一系列文章就逐步深入介绍如何定制适合自己的admin应用。

如果你觉得英文界面不好用,可以在setting.py 文件中修改以下选项

LANGUAGE_CODE = 'en-us'  #LANGUAGE_CODE = 'zh-hans'

一、认识ModelAdmin

管理界面的定制类,如需扩展特定的model界面需从该类继承。

二、注册medel类到admin的两种方式:

<1>   使用register的方法

admin.site.register(Book,MyAdmin)  # 注册多表

<2>   使用register的装饰器

@admin.register(Book)  # 注册单表

三、掌握一些常用的设置技巧

  •     list_display:     指定要显示的字段
  •     search_fields:  指定搜索的字段
  •     list_filter:        指定列表过滤器
  •     ordering:       指定排序字段
from django.contrib import admin
from app01.models import *
# Register your models here.

# @admin.register(Book)#----->单给某个表加一个定制
class MyAdmin(admin.ModelAdmin):
    list_display = ("title","price","publisher")
    search_fields = ("title","publisher")
    list_filter = ("publisher",)
    ordering = ("price",)
    fieldsets =[
        (None,               {'fields': ['title']}),
        ('price information', {'fields': ['price',"publisher"], 'classes': ['collapse']}),
    ]

admin.site.register(Book,MyAdmin)
admin.site.register(Publish)
admin.site.register(Author)

参考文献:http://www.admin10000.com/document/2220.html

django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查,而使用django admin 则需要以下步骤:

  • 创建后台管理员
  • 配置url
  • 注册和配置django admin后台管理页面

1、创建后台管理员

python manage.py createsuperuser

2、配置后台管理url

url(r'^admin/', include(admin.site.urls))

3、注册和配置django admin 后台管理页面

a、在admin中执行如下配置

from django.contrib import admin
  
from app01 import  models
  
admin.site.register(models.UserType)
admin.site.register(models.UserInfo)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

b、设置数据表名称

class UserType(models.Model):
    name = models.CharField(max_length=50)
  
    class Meta:
        verbose_name = '用户类型'
        verbose_name_plural = '用户类型'

c、打开表之后,设定默认显示,需要在model中作如下配置

class UserType(models.Model):
    name = models.CharField(max_length=50)
  
    def __unicode__(self):
        return self.name
from django.contrib import admin
  
from app01 import  models
  
class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
  
  
admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

d、为数据表添加搜索功能

from django.contrib import admin
  
from app01 import  models
  
class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')
  
admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

e、添加快速过滤

from django.contrib import admin
  
from app01 import  models
  
class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')
    list_filter = ('username', 'email')
      

admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

更多:http://docs.30c.org/djangobook2/chapter06/

Views请求的其他信息

分析过程:
1、print(type(request)),得到如下返回信息
2、提取:from django.core.handlers.wsgi import WSGIRequest
3、查看源码:request.environ
4、print(request.environ) 一堆字典
5、for循环: for k, v in request.environ.items(): print(k , v)
6、提取用户以什么方式访问的信息:request.environ['HTTP_USER_AGENT']

后记

数据库查询排序问题:

obj = User.objects.filter(name='uson').order_by('-box')
obj = User.objects.filter(name='uson').order_by('-nid')
obj = User.objects.filter(name='uson').order_by('-name')...
obj.save()

Ajax字典嵌套问题:

$.ajax({
	url: '/index/',
	# data: {'k': 'v', 'list': [1,2,3,4], 'k3':{'k1': 'v'}}, 字典嵌套,后台也是接收不到的,只能先序列化成字符串
	data: {'k': 'v', 'list': [1,2,3,4], 'k3': JSON.stringfy({'k1': 'v'}))},
	type: 'POST',
	dataType: 'JSON':
	traditional: true,
	success:function(d){
		location.reload()              # 刷新
		location.href = "某个地址"     # 跳转
	}
})

字段的索引的几种区分:

db_index=True 只能加速查找
unique=True 加速查找,限制列值唯一
primary=True 加速查找,限制列值唯一(不能为空)

request总结:

request.POST(由request.body中字典形式提取数据)
request.FILES(由request.body中字典形式提取数据)
request.body (包含所有内容的原生值)

request.GET
request.POST.getlist
request.COOKIES
request.method(POST/GET/PUT...)
request.META(安卓标识,ios标识等)
request.path_info
request.session
....

猜你喜欢

转载自www.cnblogs.com/uson/p/11593237.html