著名的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等缓存系统联用,更出色的表现,更快的加载速度。 国际化
完全支持多语言应用,允许你定义翻译的字符,轻松翻译成不同国家的语言。
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
开发服务器,即开发时使用,一般修改代码后会自动重启,方便调试和开发,但是由于性能问题,建议只用来测试,
不要用在生产环境。
创建表:python manage.py makemigrations 同步数据库: python manage.py migrate
注意:在开发过程中,数据库同步误操作之后,难免会遇到后面不能同步成功的情况,解决这个问题的一个简单粗暴方法是把migrations目录下的脚本(除__init__.py之外)全部删掉,再把数据库删掉之后创建一个新的数据库,数据库同步操作再重新做一遍。
所以我们需要为进入这个项目的后台创建超级管理员:需要先同步数据库
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
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
- render:只会返回页面内容,但是未发送第二次请求
- 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()) 不仅变量多写一次,效果也差
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 %}
使用:
- {% 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 %}
- {% 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
- {% 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>
- {% url %}
引用路由配置的地址
<form action="{% url "bieming"%}" >
<input type="text">
<input type="submit"value="提交">
{%csrf_token%}
</form>
- {{% with %}}
用更简单的变量名替代复杂的变量名
{% with total=fhjsaldfhjsdfhlasdfhljsdal %}
{{ total }}
{% endwith %}
- {{% verbatin %}}
禁止render
{% verbatim %}
{{ hello }}
{% endverbatim %}
- {{% load %}}:加载标签库
------变量过滤器(filter)的使用
- default
- 如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。
- length
- 返回值的长度
- filesizeformat
- 将值格式化为一个人类可读的文件尺寸
- {{ value|filesizeformat }}
-
value
是 123456789,输出将会是117.7 MB
。
- date
- 如果value=datetime.datetime.now()
- {{value|date:"Y-m-d"}}
- slice
- 切片和字符串一样
- value="hello world"
- {{value|slice:"2:-1"}}
- truncatechars
- 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾
- 参数:要截断的字符数
- <p>截断字符:{{ content|truncatechars:20 }}</p>
- 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 %}