Django - 模式、简单使用

时间:2021-09-01 21:05:21

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

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

  Django - 模式、简单使用

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

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

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

Django - 模式、简单使用

Django 特点
强大的数据库功能
拥有强大的数据库操作接口(QuerySet API),如需要也能执行原生SQL。 自带强大后台
几行简单的代码就让你的网站拥有一个强大的后台,轻松管理内容! 优雅的网址
用正则匹配网址,传递到对应函数,随意定义,如你所想! 模板系统
强大,易扩展的模板系统,设计简易,代码,样式分开设计,更容易管理。 注:前后端分离时,也可以用Django开发API,完全不用模板系统。 缓存系统
与Memcached, Redis等缓存系统联用,更出色的表现,更快的加载速度。 国际化
完全支持多语言应用,允许你定义翻译的字符,轻松翻译成不同国家的语言。
 django的流程和命令行                                    

1、创建一个Django对象

django-admin startproject mysite

  Django - 模式、简单使用

  • 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

  Django - 模式、简单使用

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

  Django - 模式、简单使用

8、清空数据库

python manage.py  flush

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

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

jango-admin.py  help  startapp

10、启动交互界面

python manage.py  shell
 
  视图控制 - views                                 
路由配置系统urlpatterns 
 Django - 模式、简单使用
 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 %}
  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
  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>
  4. {% url %}
    •  引用路由配置的地址
      <form action="{% url "bieming"%}" >
      <input type="text">
      <input type="submit"value="提交">
      {%csrf_token%}
      </form>
  5. {{% with %}}
    • 用更简单的变量名替代复杂的变量名
      {% with total=fhjsaldfhjsdfhlasdfhljsdal %}
      {{ total }}
      {% endwith %}
  6. {{% verbatin %}}
    •  禁止render
      {% verbatim %}
      {{ hello }}
      {% endverbatim %}
  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 }} # {{ 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 %}