web框架本质
socket + 业务逻辑框架实现socket tonado node.js使用WSGI实现socket django flask
自己实现框架思路
wsgiref socket路由系统自己写逻辑(views)jinja2 模板引擎(templates) 实现动态页面,修改返回给浏览器的字符串去db取数据(models)
web框架流程
流程: wsgi --> 路由系统 -- views(核心逻辑) --- template(拿html) --- )db (model)1 用户请求到wsgi wsgi整理用户请求env,加上一个返回数据的conn,传给后面路由系统2 请求到路由系统3 请求到view, 核心逻辑3 tpl 拿模板 模板引擎 jinja24 数据库拿数据 ORM(Model)5 合在一起6 使用 步骤 1 传过来的conn,回传数据
install django and create a django project
pip install django=1.9.5django-admin startproject my_site 创建工程cd mysitepython manage.py startapp monitor 创建APPpython manage.py startapp cmdb 创建APP1python manage.py runserver 0.0.0.0:9999这几条命令然并卵,可以在pycharm上面图形化操作
来吧,开始django吧
全局配置
一般一看就明白,添加一个新的STATICFILES_DIRS = ( os.path.join(BASE_DIV, "statics"), ) js css img放在这里
后台管理manage.py 命令
python manage.py makemigrationspython manage.py migratepython manage.py createsuperuser # 创建超级用户管理后台python manage.py shell在settings 里面配置数据库引擎
路由系统 urls
普通 (r"^/index/", vews.index),动态传参数 (r"^/index/(\d+)", vews.index),路由分发 (r"^/index/", include("appname.urls")),
template 模板
取值list dict object 通过.来取值li = [1,2,3]dic = {"k1":"v1", "k2":"v2"}{ { k1 }}{ { li.0 }}{ { dic.k1 }}逻辑控制{% for item in data %} { { item }} { { forloop.counter }} 特殊变量 索引 { { forloop.first }} 特殊变量 是否是第一个 { { forloop.last }} 特殊变量 是否是最后一个{% endfor %}{% if 1 == 1%}{% else %}{% endif %}母版 定义 {% block blockname %} {% endblock %} 使用: {% extend "front/xx.html" %} 经验:一般会定义4个block title css content js 子html在继承的时候一般都是修改这几块导入 直接导入一个小的元素 {% include "front_app/ss.html" %}内置函数自定义函数 -- 然并卵,直接在python中做,不就行了 分类: filter 只能穿一个参数 支持if的条件,通过管道 simple_tag 可以穿多个参数 不支持if的 条件 settings中注册APP 在APP里面创建templatetags 创建任意py文件,在里面写函数 from django import template from django.utils.safestring import mark_safe from django.template.base import resolve_variable, Node, TemplateSyntaxError register = template.Library() # 这个名字不能改 @register.filter def plus_10(arg): return arg + 10 @register.simple_tag def my_simple_time(v1,v2,v3): return v1 + v2 + v3 @register.simple_tag def my_input(id,arg): result = "" %(id,arg,) return mark_safe(result) 使用: {% load xx %} 先导入 {% k1|f1 %} {% my_simple_time 1 2 3%} 在使用,后面是参数 {% my_input 'id_username' 'hide'%}
简单数据库管理
基本说明
class注册adminadmin.site.register(CLASS)def __str__(): 为了让现实好看,在model下面覆盖此方法有个admin的页面可以使用,简单的数据库管理后台
定制admin界面
写一个定制类,继承 admin.ModelAdminclass BookAdmin(admin.ModelAdmin): list_display = ('name', 'publisher', 'publish_date') list_filter = ('publisher', 'publish_date') list_editable = ('name', 'publish_date') list_per_page = 10 # 每页显示多少 list_selected_related = () serach_fields = ('name', 'publish__name') # __ is magic # 定制详细页面 filter_horizontal = ('authors', ) # 针对多对多 Manytomany raw_id_filds = ('publisher', ) # 针对ForeignKey 国内有一个xadmin ,深度定制admin,效果很棒定制admin actionactions = [f1, ] # 在BookAdmin装饰类中新增, f1(bookAdmin, request, querySet) 是一个函数,处理逻辑的定制显示颜色在model中写一个函数,返回style在BookAdmin 装饰类中 list_display = (f1)
数据库model
写class class User(model) modes.CharField(maxlength=32) modes.IntegerField()配置settings INSTALL_APPS创建数据库python manage.py makemigrationspython manage.py migratecurd操作models.UserInfo.objects.create(username=“yangli”, password="123456")models.UserInfo.objects.create(**dict)obj = models.UserInfo(username="yangli2", password="12345")obj.save()models.UserInfo.objects.filter( ).delete()models.UserInfo.objects.filter( ).update(password="123") # 这种修改方式效率高models.UserInfo.objects.get(id=1)models.UserInfo.objects.filter( ).all()models.UserInfo.objects.filter( ).all().values(id,email) # 字典models.UserInfo.objects.filter( ).all().value_list(id,imail) # list and tuplemodels.UserInfo.objects.filter( ).first() last()models.UserInfo.objects.filter(name="yangli")models.UserInfo.objects.filter(name__exact="yangli")models.UserInfo.objects.filter(name__iexact="yangli")models.UserInfo.objects.filter(name__contains="yangli")models.UserInfo.objects.filter(name__icontains="yangli")models.UserInfo.objects.filter(name__startswith="yangli")models.UserInfo.objects.filter(name__endswith="yangli")models.UserInfo.objects.filter(name__range=[1, 3]).order_by("-name") # 排序models.UserInfo.objects.all()[0:2]连表查询# __ is magic, 可以作用于外键的属性models.Entry.objects.filter(blog__name__contains="科技模块")models.Entry.objects.filter(blog__name__icontains="tech")字段对比查询from django.db.models import Fmodels.Entry.objects.filter(n_comments__gt=F('n_pingbacks') * 2 )models.Entry.objects.filter(mode_date__gt = F('pub_date') + timedelta(days=3)) # 在发布3天后修改的所有实体添加有关联的表格:book -- publisher one-to-onebook -- authors many-to-manynew_book = Book( title = "learn python to Alex", publish_id = publish_id # class 中没有publish_id,但是可以这么用,不用传一个对象 # authors 是一个多对多的关系,先保存再添加)new_book.save()new_book.authors.add(1,2,3)new_book.authors.add(*authors_ids)返回动态数据给页面render(request, "t1.tpl", {"li":users_list}) 注意配置模板的路径 当使用post提交数据的时候,暂时先注释settings里面的csrf常用的数据库字段和属性类型:https://docs.djangoproject.com/en/1.10/ref/models/fields/#primary-keyIntegerField() FloatField()CharField() TextField()DateField()EmailField()TimeField()ImageField() FieldPathFiled() # 数据库里面存的是路径,django admin 提供直接上传的功能Filed optionnull=True # 限制dbbank=True # 限制django admin formuniq=Truedefault="default"primary_key=Truetauto_now 当前时间,创建的时候更新auto_now_add 当前时间,每次修改更新gender_choices = ((0, "female"),(1,"male"),)choices=gender_choicesvolidators = []upload_to="upload" # FileFiled() ImageField() 指定文件放在什么地方
数据库高级增删改查
content: 在test.py通过 django API 操作数据库 设置环境变量 import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "projectname.settings") import django djang.setup()
路由系统
直接路由 包含跳转路由 括号传参数 定义别名 ?P 字典传额外参数
模板 template
渲染模板 jianja2
把字典通过render()传给渲染模块, 字典的value是object,在模板里面通过 . 来取对象的属性 li = [] dic = {} user = User(name="yangli", password="123") li.1 dic.k1 user.name user.password 常见语法: {% for item in objs %} { { item }} {% endfor %} {% if forloop.count0|divisibleby:"2" %} {% else %} {% endif %} 模板小结: 没有while循环,因为while循环可能是死循环,这个后端不能够有这个 模板中不能够设置变量 当模板中使用了一个变量,render并没有传过来的时候,并不会报错,仅仅留空
模板继承
父亲: 自定允许修改的块 {% block name %} {% endblock %} 儿子: {% extend "path" %} # 儿子继承一个父类 {% block name %} # 在这里重写父亲的块 {% endblock %} # include 这个插件 {% include "app01/registor.html" %} 继承小结: 模板继承可以嵌套,父亲和爷爷辈的都可以重写 模板继承不能多继承
前端 frontend html css js jQuery ajax6