django基础之二

一、什么是架构?

        框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演。

对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

        最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。

        如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。

              正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。

        这个接口就是WSGI:Web Server Gateway Interface。

二、MVC和MTV

著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起。

模型负责业务对象与数据库的对象(ORM),视图负责与用户的交互(页面),控制器(C)接受用户的输入调用模型和视图完成用户的请求。

Django的MTV模式本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同,Django的MTV分别代表:

Model(模型):负责业务对象与数据库的对象(ORM)

Template(模版):负责如何把页面展示给用户

View(视图):负责业务逻辑,并在适当的时候调用Model和Template

       此外,Django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

三、Django的配置文件

 3.1配置静态文件路径,为了django找到本地的文件

        STATICFILES_DIRS = (

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

            )

3.2数据库引擎配置

        DATABASES = {

            'default': {

            'ENGINE': 'django.db.backends.mysql',

            'NAME':'数据库名字',

            'USER': 'root',

            'PASSWORD': 'xxx',

            'HOST': '',#默认是本地

            'PORT': '3306',

                        }

            }

        # 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替

        # 如下设置放置的与project同名的配置的 __init__.py文件中

        import pymysql

        pymysql.install_as_MySQLdb()

        3.3模板配置路径

        TEMPLATE_DIRS = (

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

            )

四、路由系统:

  URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。 

        urlpatterns = [    url(正则表达式, views视图函数,参数,别名),]          

        参数说明:      

                一个正则表达式字符串

                一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串

                可选的要传递给视图函数的默认参数(字典形式)

                一个可选的name参数

   4.1、单一路由对应

             url(r'^index$', views.index),  

        4.2、基于正则的路由 1 2      

            url(r'^index/(\d*)', views.index), 

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

        4.3、添加额外的参数 

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

        4.4、为路由映射设置名称

            url(r'^home', views.home, name='h1'),

            url(r'^index/(\d*)', views.index, name='h2'),             

            在使用模板时候使用

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

  • 模板中使用生成URL     {% url 'h2' 2012 %}
  • 函数中使用生成URL     reverse('h2', args=(2012,))      路径:django.urls.reverse
  • 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

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

            url(r'^web/',include('web.urls')),

            将路由指定到web项目下的urls文件去再分发

  4.6、命名空间

  1.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')),
]

 2. 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')
]

  3.app01.views.py

def detail(request, pk):
    print(request.resolver_match)
    return HttpResponse(pk)

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

  • v = reverse('app01:detail', kwargs={'pk':11})
  • {% url 'app01:detail' pk=12 pp=99 %}

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)
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)
from django import template
t = template.Template('My name is {{ name }}.')
c = template.Context({'name': 'Adrian'})
print t.render(c)
return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))

2模板的写法

           5.2.1 使用双大括号来引用变量

                {{ name }}    {{ age }}

                深度变量的查找(万能的句点号)

                  {{ list.0 }}   {{ dic.name }}

                 变量的过滤器(filter)的使用

                  {{obj|filter:param}}   

                1  add          :   给变量加上相应的值 

                2  addslashes   :    给变量中的引号前加上斜线

                3  capfirst     :    首字母大写

                4  cut          :   从字符串中移除指定的字符

                5  date         :   格式化日期字符串

                6  default      :   如果值是False,就替换成设置的默认值,否则就是用本来的值

                7  default_if_none:  如果值是None,就替换成设置的默认值,否则就使用本来的值

#实例:
#value1="aBcDe"
{{ value1|upper }}
<br>
#value2=5
{{ value2|add:3 }}
<br>
#value3='he  llo wo r ld'
{{ value3|cut:' ' }}
<br>
#import datetime
#value4=datetime.datetime.now()
{{ value4|date:'Y-m-d' }}
<br>
#value5=[]
{{ value5|default:'空的' }}
<br>
#value6='<a href="#">跳转</a>'
{{ value6 }}{% autoescape off %}  {{ value6 }}{% endautoescape %}{{ value6|safe }}
<br>
{{ value6|striptags }}
#value7='1234'{{ value7|filesizeformat }}
<br>
{{ value7|first }}
<br>
{{ value7|length }}
<br>{{ value7|slice:":-1" }}
<br>
#value8='http://www.baidu.com/?a=1&b=3'{{ value8|urlencode }}
<br>    
value9='hello I am yuan'

如果默认的filter不能满足使用,可以自定义.

 a、在app中创建templatetags模块(必须的) 

 b、创建任意 .py 文件,如:my_tags.py

#!/usr/bin/env python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
   
register = template.Library()
   
@register.simple_tag
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)

 c、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py :

 {% load my_tags %}    

d、使用simple_tag和filter(如何调用)

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

e、在settings中的INSTALLED_APPS配置当前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.11/ref/templates/language/

  {% if %} 条件语句

{% if num >= 100 and 8 %}
{% if num > 200 %} 
<p>num大于200</p>
{% else %}
<p>num大于100小于200</p>
{% endif %}
{% elif num < 100%}
<p>num小于100</p>
{% else %}
<p>num等于100</p>
{% endif %}{% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量
{% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,
例如下面的标签是不合法的:{% if obj1 and obj2 or obj3 %}

 {% for %}

            {% for %}标签允许你按顺序遍历一个序列中的各个元素,每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容

<ul>{% for obj in list %} 
<li>{{ obj.name }}</li>{% endfor %}</ul>
#在标签里添加reversed来反序循环列表:  
  {% for obj in list reversed %}    ...    {% endfor %}
#{% for %}标签可以嵌套:  
  {% for country in countries %}     
   <h1>{{ country.name }}</h1>   
     <ul>         {% for city in country.city_list %}     
       <li>{{ city }}</li>         {% endfor %}        </ul>    {% endfor %}
#系统不支持中断循环,系统也不支持continue语句,{% for %}标签内置了一个forloop模板变量,
#这个变量含有一些属性可以提供给你一些关于循环的信息1,forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1:    {% for item in todo_list %}        <p>{{ forloop.counter }}: {{ item }}</p>    {% endfor %}2,forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为03,forloop.revcounter4,forloop.revcounter05,forloop.first当第一次循环时值为True,在特别情况下很有用:        {% for object in objects %}            {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}            {{ object }}           </li>      {% endfor %}     
 # 富有魔力的forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就消失了# 如果你的模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它
# Django会在for标签的块中覆盖你定义的forloop变量的值# 在其他非循环的地方,你的forloop变量仍然可用
#{% empty %}{{li }}      {%  for i in li %}          <li>{{ forloop.counter0 }}----{{ i }}</li>      {% empty %}          <li>this is empty!</li>      {% endfor %}#         [11, 22, 33, 44, 55]#            0----11#            1----22#            2----33#            3----44#            4----55

{%csrf_token%}:csrf_token标签

        用于生成csrf_token的标签,用于防治跨站攻击验证。注意如果你在view的index里用的是render_to_response方法,不会生效

        其实,这里是会生成一个input标签,和其他表单标签一起提交给后台的。

        {% url %}:  引用路由配置的地址

        {% with %}:用更简单的变量名替代复杂的变量名

        {% load %}: 加载标签库 

六、模板继承

        我们制作某个页面,想让其他页面也继承一些样式,可以将此页面设置成模板。

         将需要修改的内容 

            {%  block  模块名称  %} 

                    内容

            {% endblock %}

        在需要继承模板的页面第一行添加以下内容才可以继承

            {% extends "base.html" %}

        模板使用方式:

            直接写需要修改的块,不写默认全部继承模板的内容

            {% block  模块名称 %}

                修改的内容

             {% endblock %}

           如果需要使用模板的内容,又想添加一些内容,可以如下设置

             {% block  模块名称 %}

                {% include %}

                修改的内容

             {% endblock %}

七、视图 views.py

        http请求中产生两个核心对象:

            http请求:HttpRequest对象

            http响应:HttpResponse对象

         path:请求页面的全路径,不包括域名          method:请求中使用的HTTP方法的字符串表示。全大写表示。例如                 if  req.method=="GET":                      do_something()                     elseif req.method=="POST":                     do_something_else()          GET:         包含所有HTTP GET参数的类字典对象          POST:       包含所有HTTP POST参数的类字典对象              服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过               HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用               if req.POST来判断是否使用了HTTP POST 方法;应该使用  if req.method=="POST"         COOKIES:     包含所有cookies的标准Python字典对象;keys和values都是字符串。         FILES:包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:                   filename:      上传文件名,用字符串表示                   content_type:   上传文件的Content Type                   content:       上传文件的原始内容         user:       

                   是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前                   没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你                   可以通过user的is_authenticated()方法来辨别用户是否登陆:                   if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware                   时该属性才可用          session:    

            唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。       HttpResponse对象      

        render()(推荐)

        render_to_response(),

        redirect("路径")

        locals():    可以直接将函数中所有的变量传给模板

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java成神之路

jdom学习读取XML文件

用JDOM读取XML文件需先用org.jdom.input.SAXBuilder对象的build()方法创建Document对象,然后用Document类、El...

553
来自专栏草根专栏

用ASP.NET Core 2.0 建立规范的 REST API -- DELETE, UPDATE, PATCH 和 Log

本文所需的一些预备知识可以看这里: http://www.cnblogs.com/cgzl/p/9010978.html 和 http://www.cnblog...

822
来自专栏xingoo, 一个梦想做发明家的程序员

Elasticsearch 动态映射——自动检测

ES中有一个非常重要的特性——动态映射,即索引文档前不需要创建索引、类型等信息,在索引的同时会自动完成索引、类型、映射的创建。 那么什么是映射呢?映射就是描...

1745
来自专栏大内老A

ASP.NET Core的配置(4):多样性的配置来源[上篇]

较之传统通过App.config和Web.config这两个XML文件承载的配置系统,ASP.NET Core采用的这个全新的配置模型的最大一个优势就是针对多种...

1816
来自专栏DOTNET

【翻译】MongoDB指南/CRUD操作(二)

【原文地址】https://docs.mongodb.com/manual/ MongoDB CRUD操作(二) 主要内容: 更新文档,删除文档,批量写操作,S...

2958
来自专栏coder修行路

jS正则和WEB框架Django的入门

JS正则 -test 判断字符串是否符合规定的正则表达式 -exec 获取匹配的数据 test的例子: ? 从上述的例子我们可以看出,如果rep.test匹配到...

1776
来自专栏Python自动化测试

Django路由系统学习(四)

在Django的执行原理中已经学习了django的执行过程,本小节重点来介绍django的路由系统,也就是url的部分,在前面的Django的执行原理中...

852
来自专栏程序你好

JavaScript调试和优化,深入研究谷歌Chrome浏览器开发工具(一)

Chrome DevTools集成了许多子工具,用于在客户端上调试web应用程序,比如记录性能配置文件和检查动画——主要是通过DevTools控制台来学习web...

725
来自专栏用户2442861的专栏

windows下mongodb安装与使用整理

3.创建文件夹d:\mongodb\data\db、d:\mongodb\data\log,分别用来安装db和日志文件,在log文件夹下创建一个日志文件Mong...

622
来自专栏我的博客

TP入门第十天

1、自动验证 数据对象是由表单提交的$_POST数据创建。需要使用系统的自动验证功能,只需要在Model类里面定义$_validate属性,是由多个验证因子组成...

3175

扫码关注云+社区