1、如何创建一个Django项目
django-admin startproject 项目名 此时只是创建了一个django项目,要想使用还需创建应用,这里的配置是一个全局的内容
当我们创建好以后,会看到一个这样的目录结构:
2、如何创建一个应用
python manage.py startapp 应用名 此时就创建了一个应用,例如支付功能、论坛功能等
当我们创建好以后,会看到一个这样的目录结构:
※:一个项目里应该有多个应用,不应该是单独一个功能。
3、如何让Django项目跑起来
python manage.py runserver [ip] port ip可以省略不写默认本机,端口号需指明
在第一次跑Django时遇见了一个错误 “ You have 13 unapplied migration(s). Your project may not work properly until you apply ...报错 ”,执行 python manage.py migrate ,它可以让我们在修改Model后可以在不影响现有数据的前提下重建表结构。
Djang有一个好处就是修改页面以后就不需要自己重启django,它会自动进行重启,但是修改setting以后需要自己重启。
4、配置文件
settings: INSTALLED_APPS 用于存放应用,每创建一个应用都要加入这个列表中。如果是在pycharm创建的,会自动添加应用。
TEMPLATES下 的 DIRS:这里配置了去哪里找html,解决在templates找不到html。dir下面放了从哪里找到文件。如果是在pycharm创建的,会自动设置好路径。
1、路由系统(django url)
在urls文件中,每一个url对应一个视图函数。所以 url(r'admin/', admin.func) ,加上r,因为这是一个正则表达式并不是一个具体的路径。
格式:urlpatterns = [ url(正则表达式,views视图函数,参数,别名) ] ,例如
urlpatterns = [
url(r'register/', views.register, name='reg'),
]
※:Django在执行路由系统时,会把要请求的路径放到 urlpatterns 中进行逐个比对,当匹配成功时就退出,不会再往后进行查找。
因为第一个参数为正则表达式,当有正则表达式的分组时,就产生了两种分组情况,无命名分组和命名分组。
无命名分组: url(r'art/(\d{4})', views.art), 会在对应的视图函数加上一个参数进行接收分组的内容,参数名可随意写
命名分组: url(r'art/(?P\d{4})', views.art) 也会在对应的视图函数加上一个参数进行接收分组的内容,但是参数名不可随意写,应该和分组的名字相同。
name 参数起到一个别名的作用:在前端页面使用别名,这样修改文件的路径也不会影响到前端页面,只要不修改别名就不会影响前端页面。具体如下使用:
在urls文件进行urlpattern的匹配
urlpatterns = [
url(r'register/', views.register, name='reg'),
url(r'login/$', views.login), # 写url结尾尽量加上'$', 防止正则表达式的误配
]
---------------------------------------------------------------------------------
此时在前端页面
{% load staticfiles %} 需要引入静态文件
URL的分发:
为什么会有URL的分发,是因为不可能所有的 url 都写到最外面的urls文件内,因为一个项目包含多个应用,所以需要对URL进行分发,
具体如下:
url (r'blog/', include('blog.urls')) 凡是包含blog的url都发送到blog下的urls的文件内, 应用名.urls
可以对请求的类型不一样从而进行不通的操作
通过 request.method == "post" 来区分请求的类型,从而在一个函数进行两种擦操作。
测试项目时应注意是否同源。
2、视图函数(views)
两个最重要的对象 HttpRequest、HttpResponse。
1、HttpRequest的方法
path属性:请求页面的路径,不包括域名
get_full_path()方法: 全路径,带着数据的
method(): 查看请求的方式
GET()方法:get参数的类字典对象
POST()方法:post参数的类字典对象
getlist(value) 用于获得checkbox等一些列的值。
对于put方式的请求在Django中并没有request.PUT方法,只能通过request.body中去拿数据。
关于文件上传:
需要在form表单中的定义:
在后台接受时:文件的内容并不是一次性的上传过来,而是和迭代器一样
request.FILES 上传文件接收的类型是request.FILES。
request.FILES.get("img").name # 通过前台的name属性获取到文件名
request.FILES.get("img").size # 通过前台的name属性获取到文件大小
request.FILES.get("img").chunks() # 分成段的传数据、上传文件。获取文件内容
2、模板(template)
所有的 html 放在 templates 文件夹里面,需要用render方法来进行渲染,有两个参数第一个是request,必须和上面的请求对象一样,第二个参数是要返回的页面。render 的第三个参数{"name":jax},组成一个键值对,会替换html的页面中 {{ name }} 的这个元素,值为jax的views 视图函数的值。
模板的渲染时间(render) 是在后端时渲染的,django先对html文件进行渲染后再发给浏览器,对于js和css等静态文件时,一般加载不会管用,需要在最外层建一个static文件,用来存放静态文件。
要想能读出js等静态文件,需要在Django的settings文件做配置 STATICFILES_DIRS=(os.path.join(BASE_DIR, "static"),)。如果这里是statics 要是换名字,它的文件夹就得变成statics。static 和 BASE.DIR进行路径拼接,django根据这个找到真实文件的位置,STATIC_URL的值是一个关于静态文件的别名,django会通过别名找寻静态文件的位置,不会根据真实位置找到真实文件的位置,以实现修改了真实路径但不影响前端页面。所以每一个应用都应该有自己的一个static文件。所以推荐如下写法
推荐通过这种方式引入js文件, static + 文件名
但是必须在前面加上{ % load staticfiles % }。
页面的渲染方式:
HttpResponse("value") 要求的返回值必须是HttpResponse的对象
render(request, '返回的页面', locals()) 这种方式通过全部的局部变量渲染html页面。
render_to_response('返回的页面', locals()) 和上面方法一样,但是不需要再加request。
locals(): 把所有的局部变量变量全部渲染,
页面跳转:redirect("路径") url会变
HttpResponse、render_to_response、render返回的都是字符串。
变量 : 两个大括号括起来代表一个变量,如下:
{{ name }} 代表一个name变量
在前端页面输出列表、字典、类的属性值:
后台代码:
class Animal:
def __init__(self,name,age):
self.name = name
self.age = age
def login(request):
attr = ['alex', 'yuan']
dl = {"name": 123, "sex": 789}
pp = Animal("pp", 236)
return render(request,"login.html",locals())
-------------------------------------------------------------------------------------------
前端代码:
{{ attr.0 }}
{{ attr.1 }}
{{ dl.name }}
{{ dl.sex }}
{{ pp.name }}
{{ pp.age }}
在 jinja 里面没有index的方式获取元素,只有打点调用 ’ . ‘ 。
Templates对象和Context对象:
python manage.py shell 打开django交互模式
※ template 模板:同一个模板,多个上下文,一旦有了模板对象,就可以渲染多个context,一次模板创建多次调用render方法。
from django.template import Template, Context
t = Template("{{name}}
") # 实例一个渲染模板
c = Context({"name":"pp"}) # 实例一个渲染的数据
t.render(c) # 开始渲染
Out[5]: 'pp
'
变量过滤器:
凡是出现两个大括号的都为变量。
一些简单的过滤器:
{{ a|length }} 打印变量a的长度。
{{ a|first }} 打印变量a的第一个字母。
{{ a|last }} 打印变量a的最后一个字母。
{{ a|capfirst }} 变量a的首字母大写。
{{ age|add:12 }} 返回的值为age+12,给变量加上值。
更高级的过滤器:
{{ a|cut:"p" }} 从字符串中移除指定的字符。 从变量a中移除所有p字母。 lamp -------> lam
{{ a|default:"block" }} 如果一个变量为空,就显示default的值。 " " -------> block
{{ a|default_if_none:"block" }} 如果是none值显示default的值。 " " -------> block
{{ a|date:"Y-m-d" }} 格式化日期字符串。 2019-03-18
{{ a|slice:":-1" }} 切片。 "popular" -------> popula
{{ a|urlencode }} 进行编码。
后台创建一个标签前台显示:
a = "click"
方法一:
{{ a|safe }} 需要加上safe,默认的是不安全的,防止xss攻击。
方法二:
{% autoescape off %} // 用于关闭安全机制
{{ a }}
{% endautoescape %}
自定义过滤器:
必须遵循以下步骤:
1、在应用(app)中创建 templatetags包 。
2、创建任意py文件,例如my_tag.py。
前三行必须这样写:
from django import template
from django.utils.safestring import mark_safe
register = template.Library() // 变量名必须是register,不能变
3、 通过load导入文件。 {% load my_tag%}
4、 必须在 install_app 注册。
自定义的一个过滤器: 只能传一个参数。
@register.filter
def mul(x, y):
return x*y
自定义的一个标签: 不能用在控制语句。
@register.simple_tag
def add(x, y):
return x+y
标签的使用:
※:在这里没有缩进的影响,以 {%%} 出现的都是标签。
标签一般都是成对出现的,例如有{% if %}就有 {% endif %},有{% for %}就有 {% endfor %},有{% with %}就有 {% endwith %}。
判断标签:
{% if age>10%}
{% if sex=="male"%}
male
{% else %}
female
{% elif age>20%}
大于10小于20
{%else%}
小于10
{% end if %}
循环标签:
{% for item in ulist %}
{% if forloop.first %} // 当第一次的循环时值为True
2333
{% endif %}
{{ forloop.revcounter0 }}
// 倒序打印
{{ forloop.counter0 }}
// 正序打印,索引值从0开始的索引
{{ forloop.revcounter }}
// 倒序打印
{{ forloop.counter }}
// 正序打印,索引值从1开始的索引
{% endfor %}
如果for循环包括empty标签,要遍历的元素为空则不会执行其他的逻辑代码,直接执行empty标签。
{% for item in ulist %}
{% empty %}
{% endfor %}
csrf_token标签:用于防止跨站攻击,在views用到render_to_response 则不会生效,这个验证可以通过在settings里面关掉。
也可以通过引入特殊的装饰器关闭csrf_token
from django.views.decorators.csrf import csrf_exempt 加上这个装饰器不受csrf保护,即便在settings里设置保护
from django.views.decorators.csrf import csrf_protect 加上这个装饰器受csrf保护,即便在settings里设置不保护
、with标签:用简单的变量名替换复杂的变量名,只能做用在with域。
{%with totally=sldkgfjlkdshnvcklfh %}
{{ totally }}
{% endwith %}
verbatim标签: 禁止render
{% verbatim %}
{{hello}} //这样禁止了{{hello}} 的渲染
{% endverbatim %}
url标签:引用路由配置的地址
{% url “reg” %} 一般用别名
{%load%} 加载标签库
{% load staticfiles %}
include 标签
该标签允许在(模板中)包含其它的模板的内容。 标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串。 每当在多个模板中出现相同的代码时,就应该考虑是否要使用 {% include %} 来减少重复。
{% include "index.html" %}
extends 标签、block标签:
block标签用于包裹要修改的部分:
{% block content %} // content是唯一的标识
欢迎使用~
// 其他页面要修改的内容
{% endblock %}
在其他模板进行调用时,应注明相同的id
{% block content%} // 应和前面的id相同
{{ block.super }} // 调用父级的模板
23333
{% endblock %}
extends标签用于继承其他模板:
{% extends "base.html" %}