Django

蓝咒 提交于 2020-05-02 03:10:15

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

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

  

 

Django是MTV模式,两者没有本质上的差别,也是为了各组件之间保持松耦合关系。

  • Model(模型):负责业务对象与数据库的对象(ORM)
  • Template(模版):负责如何把页面展示给用户----------V
  • View(视图):负责业务逻辑,并在适当的时候调用Model和Template---------------C

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

Django 特点
强大的数据库功能
拥有强大的数据库操作接口(QuerySet API),如需要也能执行原生SQL。

自带强大后台
几行简单的代码就让你的网站拥有一个强大的后台,轻松管理内容!

优雅的网址
用正则匹配网址,传递到对应函数,随意定义,如你所想!

模板系统
强大,易扩展的模板系统,设计简易,代码,样式分开设计,更容易管理。

注:前后端分离时,也可以用Django开发API,完全不用模板系统。

缓存系统
与Memcached, Redis等缓存系统联用,更出色的表现,更快的加载速度。

国际化
完全支持多语言应用,允许你定义翻译的字符,轻松翻译成不同国家的语言。

 

 

 django的流程和命令行                                    

 1、创建一个Django对象

django-admin startproject mysite

  

  • manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库等。
  • settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
  • urls.py ----- 负责把URL模式映射到应用程序。
  • templates 文件夹
  • --------->views.py 中的函数渲染templates中的Html模板,得到动态内容的网页,当然可以用缓存来提高速度。

2、创建一个应用

python manage.py startapp blog(应用名称)

  这是一个空白pro包含的内容,每多一个应用多一个文件

C:.
│  db.sqlite3
│  manage.py
│
├─blog
│  │  admin.py
│  │  apps.py
│  │  models.py
│  │  tests.py
│  │  views.py
│  │  __init__.py
│  │
│  └─migrations
│          __init__.py
│
└─mysite
    │  settings.py
    │  urls.py
    │  wsgi.py
    │  __init__.py
    │
    └─__pycache__
            settings.cpython-35.pyc
            urls.cpython-35.pyc
            wsgi.cpython-35.pyc
            __init__.cpython-35.pyc

把 blog 加入到settings.py中的INSTALLED_APPS中

新建的 app 如果不加到 INSTALL_APPS 中的话, django 就不能自动找到app中的模板文件(app-name/templates/下的文件)和静态文件(app-name/static/中的文件)

 

3、settings配置

TEMPLATES

       STATICFILES_DIRS=(
            os.path.join(BASE_DIR,"statics"),
        )

       STATIC_URL = '/static/' 
       #  我们只能用 STATIC_URL,但STATIC_URL会按着你的STATICFILES_DIRS去找#4  根据需求设计代码
           url.py
           view.py

4、使用模板

render(req,"index.html")

5、启动Django项目

python  manage.py runserver  127.0.0.1:8090
开发服务器,即开发时使用,一般修改代码后会自动重启,方便调试和开发,但是由于性能问题,建议只用来测试,
不要用在生产环境。
6、连接数据库,操作数据
创建表:python manage.py makemigrations  

同步数据库:  python manage.py migrate  

  注意:在开发过程中,数据库同步误操作之后,难免会遇到后面不能同步成功的情况,解决这个问题的一个简单粗暴方法是把migrations目录下的脚本(除__init__.py之外)全部删掉,再把数据库删掉之后创建一个新的数据库,数据库同步操作再重新做一遍。     

7、当访问http://127.0.0.1:8000/admin/时:  

所以我们需要为进入这个项目的后台创建超级管理员:需要先同步数据库

python manage.py createsuperuser
# 修改 用户密码可以用:
  python manage.py changepassword username

  

  设置好用户名和密码后便可登录啦!

  

8、清空数据库

python manage.py  flush

此命令会询问是 yes 还是 no, 选择 yes 会把数据全部清空掉,只留下空表。

9、查询某个命令的详细信息

jango-admin.py  help  startapp

10、启动交互界面

python manage.py  shell

 

 
  视图控制 - views                                 
路由配置系统urlpatterns 
 
url(正则表达式, views视图函数,参数,别名),
之后可以通过{%url 别名%}调用
include:url分发,把符合特定规则的url发送到特定的处理位置
1、一旦匹配成功则不再继续
2若要从URL 中捕获一个值,只需要在它周围放置一对圆括号3、不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
4、每个正则表达式前面的'r' 是可选的但是建议加上。
# 有名分组(就是给分组起个名字,这样定义的好处就是按照关键字参数去传参了,指名道姓的方式)
 url(r'^article/(?P<year>\d{4})/(?P<month>\d{2})$', views.year_month_hasname)

 

path:       请求页面的全路径,不包括域名,get方式请求体
get_full_path()  :请求路径(路径和数据都会拿到)
method:     请求中使用的HTTP方法的字符串表示。全大写表示。例如

               if  req.method=="GET":

                         do_something()

               elif req.method=="POST":

                         do_something_else()

GET:         包含所有HTTP GET参数的类字典对象

POST:       包含所有HTTP 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支持时该属性才可用。
HttpRequest对象内容 
请求某个键下多个值时:request.POST.getlist("hobby")

 

render函数 

渲染

响应返回的是一个真正的html文件,但在发送时需要对html修改时,需要用到render函数-替换指定位置的内容。

返回一个HTTPResponse对象

render(request, template_name[, context])----------------》底层也是调用的HTTPResponse

  • request:HttpRequest对象的一个实例
  • template_name:要替换的html文件,
  • context:添加到模板上下文的一个字典。
  • render_to_response(template_name[,context])----------------->不用在写requests了

redirect函数 

 跳转

  redirect(request, template_name[, context])----------------》底层也是调用的HTTPResponse

 

  redicert和render的区别                      
  1. render:只会返回页面内容,但是未发送第二次请求
  2. redirect:发挥了第二次请求,url更新 
①跳转后url会显示之后的,而渲染不会。

②
以登录界面-------》首页为例
def denglu(request):
    
    **********
    return  redirect("/login")
    
    name="yuan"
    #return render(request,"login.html",locals())

def login(request):
    name="yuan"
    render("login.html",locals())

不仅变量多写一次,效果也差

 

  模板 - Template                                 
 
 模板并不是真正的html文件 = html代码 + 模板代码
语法格式  {{ var_name }}
 
 
------Template和Context对象
def current_time(req):
    # ================================原始的视图函数
    import datetime
    # now=datetime.datetime.now()
    # html="<html><body>现在时刻:<h1>%s.</h1></body></html>" %now


    # ================================django模板修改的视图函数
    from django.template import Template,Context
    now=datetime.datetime.now()
    t=Template('<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>')
    #t=get_template('current_datetime.html')
    c=Context({'current_date':str(now)})
    html=t.render(c)

    return HttpResponse(html)


    #另一种写法(推荐)
    # import datetime
    # now=datetime.datetime.now()
    # return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})








当替换的变量太多时,也可以使用local()导入函数内的所有值。
替换变量

 

------标签(tag)的使用

语法格式:  {% tag %}

使用:

  1. {% 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 %}
      View Code
  2. {% for  %}
    • <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开始计数,第一次循环设为0
      3,forloop.revcounter
      4,forloop.revcounter0
      5,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
      View Code
  3. {% crsf_token %}
    • 提交数据的时候就会做安全机制,当你点击提交的时候会出现一个forbbiddon
      的错误,就是用setting配置里的scrf做安全机制的,那么我们可以吧它给注释了,,,
      或者在form表单下面添加一个{% csrf_token %},,,
      这才是真正解决的办法,注释不是解决的办法
      <h3>scrf_token</h3>
      <form action="/tag/" method="post">
          {% csrf_token %}
          <p><input type="text" name="haiyan"></p>
          <input type="submit">
      </form>
      View Code
  4. {% url %}
    •  引用路由配置的地址
      <form action="{% url "bieming"%}" >
                <input type="text">
                <input type="submit"value="提交">
                {%csrf_token%}
      </form>
      View Code
  5. {{% with %}}
    • 用更简单的变量名替代复杂的变量名
      {% with total=fhjsaldfhjsdfhlasdfhljsdal %} 
      {{ total }}
      {% endwith %}
  6. {{% verbatin %}}
    •  禁止render
      {% verbatim %}
               {{ hello }}
      {% endverbatim %}
      View Code
  7. {{% load %}}:加载标签库

 

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

语法格式:   {{obj|filter_name:param}}
  1. default
    • 如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。
  2. length
    • 返回值的长度
  3. filesizeformat
    • 将值格式化为一个人类可读的文件尺寸
    • {{ value|filesizeformat }}
    •  value 是 123456789,输出将会是 117.7 MB
  4. date
    • 如果value=datetime.datetime.now()
    • {{value|date:"Y-m-d"}}
  5. slice
    • 切片和字符串一样
    • value="hello  world"
    • {{value|slice:"2:-1"}}
  6. truncatechars
    • 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾
    • 参数:要截断的字符数
    • <p>截断字符:{{ content|truncatechars:20 }}</p>
  7. safe
    • Django的模板中会对HTML标签和JS等语法标签进行自动转义。
    • value="<a href="">点击</a>"
    • {{value}}---------------》会显示字符串
    • {{value|safe}}---------------------》会显示“点击”

 

------自定义标签和过滤器 

1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
2、在app中创建templatetags模块(模块名只能是templatetags)
3、在templatetags里面创建任意 *.py 文件,
如:my_tags.py
from django import template
from django.utils.safestring import mark_safe
 
register = template.Library()   #register的名字是固定的,不可改变

@register.filter   过滤器
def multi(x,y):
    return x*y

@register.simple_tag  标签
def multitag(x,y,z):
    return x*y*z
@register.simple_tag  标签
def my_input(id,arg):
   result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
   return mark_safe(result)
4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py

{% load my_tags %} 

{% load xxx %}  
      
# num=12
{{ num|multi:2 }} #24
 
{{ num|multi:"[22,333,4444]" }}   相当于复制了,吧[22,333,4444]乘了num遍
{% multitag 2 5 6 %} 参数不限,但不能放在if for语句中 {% simple_tag_multi num 5 %}

 

 
自定义过滤器函数的参数只能两个,可以进行逻辑判断
自定义标签无参数限制,不能进行逻辑判断



{% if i|multi:5 > 1000 %}   <!-- 判断i*5>1000 -->
    <p>大于{{ i }}</p>
{% else %}
    <p>小于等于{{ i }}</p>
{% endif %}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!