前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >django基础之二

django基础之二

作者头像
程序员同行者
发布2018-07-02 17:18:21
1.6K0
发布2018-07-02 17:18:21
举报
文章被收录于专栏:程序员同行者程序员同行者

一、什么是架构?

        框架,即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() 方法
代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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 中获取的数据插入到模版中,最后将信息返回给用户

代码语言:javascript
复制
def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
代码语言:javascript
复制
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
代码语言:javascript
复制
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)
代码语言:javascript
复制
from django import template
t = template.Template('My name is {{ name }}.')
c = template.Context({'name': 'Adrian'})
print t.render(c)
代码语言:javascript
复制
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,就替换成设置的默认值,否则就使用本来的值

代码语言:javascript
复制
#实例:
#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

代码语言:javascript
复制
#!/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 :

代码语言:javascript
复制
 {% load my_tags %}    

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

代码语言:javascript
复制
{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}

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

代码语言:javascript
复制
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 %} 条件语句

代码语言:javascript
复制
{% 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 %}之间的所有内容

代码语言:javascript
复制
<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():    可以直接将函数中所有的变量传给模板

代码语言:javascript
复制
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-01-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档