# 建议安装最新LTS版
pip3 install django==1.11.11
django-admin startproject mysite
mysite/
├── manage.py # Django项目里面的工具,通过它可以调用django shell和数据库等。
└── mysite # 项目目录
├── __init__.py
├── settings.py # 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
├── urls.py # 路由 --> 负责把URL模式映射到应用程序。
└── wsgi.py # runserver命令就使用wsgiref模块做简单的web server
python manage.py startapp app01
app01
├── __init__.py
├── admin.py
├── apps.py
├── migtations
├── __init__.py
├── models.py
├── tests.py
└── views.py
# 启动服务
python manage.py runserver 127.0.0.1:8000
# 同步更改数据库表或字段
python manage.py syncdb
注意:Django 1.7.1 及以上的版本需要用以下命令
python manage.py makemigrations
python manage.py migrate
# 清空数据库
python manage.py flush
# 创建超级管理员
python manage.py createsuperuser
# 按照提示输入用户名和对应的密码就好了邮箱可以留空,用户名和密码必填
# 修改用户密码可以用:
python manage.py changepassword username
# Django 项目环境终端
python manage.py shell
# Django 项目环境终端
python manage.py dbshell
# 更多命令
python manage.py
STATIC文件还可以配置STATICFILES_DIRS,指定额外的静态文件存储位置。(STATIC_URL的含义与MEDIA_URL类似)
#为了后端的更改不会影响前端的引入,避免造成前端大量修改
STATIC_URL = '/static/' #引用名
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"statics") #实际名 ,即实际文件夹的名字
)
#django对引用名和实际名进行映射,引用时,只能按照引用名来,不能按实际名去找
#
#------error-----不能直接用,必须用STATIC_URL = '/static/':
#
STATIC_URL = '/static/'
STATICFILES_DIRS=(
('hello',os.path.join(BASE_DIR,"app01","statics")) ,
)
#
STATIC_URL = '/static/'
{% load staticfiles %}
#
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。
urlpatterns = [
url(正则表达式, views视图函数,参数,别名),
]
参数说明:
一个正则表达式字符串
一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
可选的要传递给视图函数的默认参数(字典形式)
一个可选的name参数
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
'''
NOTE:
1、一旦匹配成功则不再继续
2、若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
3、不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
4、每个正则表达式前面的'r' 是可选的但是建议加上。
一些请求的例子:
/articles/2005/3/ 不匹配任何URL 模式,因为列表中的第三个模式要求月份应该是两个数字。
/articles/2003/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。
/articles/2005/03/ 请求将匹配列表中的第三个模式。Django 将调用函数
views.month_archive(request, '2005', '03')。
'''
# 设置项是否开启URL访问地址后面不为/跳转至带有/的路径
APPEND_SLASH=True
在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。在Python正则表达式中,命名正则表达式组的语法是(?P< name>pattern),其中name 是组的名称,pattern 是要匹配的模式。
下面是以上URLconf 使用命名组的重写:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/(?P[0-9]{4})/$' , views.year_archive),
url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$' , views.month_archive),
url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]{2})/$' , views.article_detail),
]
这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。例如:
/articles/2005/03/
请求将调用views.month_archive(request, year='2005', month='03')函数
/articles/2003/03/03/
请求将调用函数views.article_detail(request, year='2003', month='03', day='03')。
在实际应用中,这意味你的URLconf 会更加明晰且不容易产生参数顺序问题的错误 —— 你可以在你的视图函数定义中重新安排参数的顺序。当然,这些好处是以简洁为代价;有些开发人员认为命名组语法丑陋而繁琐。
URLconf 在请求的URL 上查找,将它当做一个普通的Python 字符串。不包括GET和POST参数以及域名。
例如,http://www.example.com/myapp/ 请求中,URLconf 将查找myapp/,在http://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找myapp/。URLconf 不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的POST、GET、HEAD等等 —— 都将路由到相同的函数。
每个捕获的参数都作为一个普通的Python 字符串传递给视图,无论正则表达式使用的是什么匹配方式。例如,下面这行URLconf 中:
url(r'^articles/(?P[0-9]{4})/$' , views.year_archive),
views.year_archive() 的year 参数将是一个字符串
有一个方便的小技巧是指定视图参数的默认值。 下面是一个URLconf 和视图的示例:
# URLconf
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/$', views.page),
url(r'^blog/page(?P[0-9]+)/$' , views.page),
]
# View (in blog/views.py)
def page(request, num="1"):
在上面的例子中,两个URL模式指向同一个视图views.page —— 但是第一个模式不会从URL 中捕获任何值。如果第一个模式匹配,page() 函数将使用num参数的默认值”1”。如果第二个模式匹配,page() 将使用正则表达式捕获的num 值
#At any point, your urlpatterns can “include” other URLconf modules. This
#essentially “roots” a set of URLs below other ones.
#For example, here’s an excerpt of the URLconf for the Django website itself.
#It includes a number of other URLconfs:
from django.conf.urls import include, url
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('blog.urls')),
]
URLconfs 具有一个钩子,让你传递一个Python 字典作为额外的参数传递给视图函数。
django.conf.urls.url() 函数可以接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/(?P[0-9]{4})/$' , views.year_archive, {'foo': 'bar'}),
]
在这个例子中,对于/blog/2005/请求,Django 将调用views.year_archive(request, year=’2005’, foo=’bar’)。这个技术在Syndication 框架中使用,来传递元数据和选项给视图。
urlpatterns = [
url(r'^index',views.index,name='INDEX'),
]
###################
def index(req):
if req.method=='POST':
username=req.POST.get('username')
password=req.POST.get('password')
if username=='alex' and password=='123':
return HttpResponse("登陆成功")
return render(req,'index.html')
#####################
"en">
"UTF-8">
Title
{#
视图函数,简短来说叫做视图,是一个简单的Python函数,它接受web请求,并且返回web响应。
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "It is now %s." % now
return HttpResponse(html)
'''
http请求-响应过程中有两个核心对象:
http请求对象:HttpRequest
http响应响应:HttpResponse
所在位置:django.http
'''
内部传入一个字符串参数,返回给浏览器。
def index(request):
# 业务逻辑代码
return HttpResponse("OK")
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
# 参数:
request: 用于生成响应的请求对象。
template_name:要使用的模板的完整名称,可选的参数
context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。
content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。
status:响应的状态码。默认为200。
-----------------------------------url.py
url(r"login", views.login),
url(r"yuan_back", views.yuan_back),
-----------------------------------views.py
def login(req):
if req.method=="POST":
if 1:
# return redirect("/yuan_back/")
name="yuanhao"
return render(req,"my backend.html",locals())
return render(req,"login.html",locals())
def yuan_back(req):
name="Yang"
return render(req,"my backend.html",locals())
-----------------------------------login.html
-----------------------------------my_backend.html
用户{{ name }}你好
{{var_name}}
#最好是用几个例子来说明一下。
# 首先,句点可用于访问列表索引,例如:
>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
'Item 2 is carrots.'
#假设你要向模板传递一个 Python 字典。 要通过字典键访问该字典的值,可使用一个句点:
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
'Sally is 43 years old.'
#同样,也可以通过句点来访问对象的属性。 比方说, Python 的 datetime.date 对象有
#year 、 month 和 day 几个属性,你同样可以在模板中使用句点来访问这些属性:
>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
1993
>>> d.month
5
>>> d.day
2
>>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
>>> c = Context({'date': d})
>>> t.render(c)
'The month is 5 and the year is 1993.'
# 这个例子使用了一个自定义的类,演示了通过实例变量加一点(dots)来访问它的属性,这个方法适
# 用于任意的对象。
>>> from django.template import Template, Context
>>> class Person(object):
... def __init__(self, first_name, last_name):
... self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
'Hello, John Smith.'
# 点语法也可以用来引用对象的方法。 例如,每个 Python 字符串都有 upper() 和 isdigit()
# 方法,你在模板中可以使用同样的句点语法来调用它们:
>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
'123 -- 123 -- True'
# 注意这里调用方法时并* 没有* 使用圆括号 而且也无法给该方法传递参数;你只能调用不需参数的
# 方法。
方法 | 介绍 |
---|---|
add | 给变量加上相应的值 |
addslashes | 给变量中的引号前加上斜线 |
capfirst | 首字母大写 |
cut | 从字符串中移除指定的字符 |
date | 格式化日期字符串 |
default | 如果值是False,就替换成设置的默认值,否则就是用本来的值 |
default_if_none | 如果值是None,就替换成设置的默认值,否则就使用本来的值 |
- 标签(tag)的使用(使用大括号和百分比的组合来表示使用tag)
语法格式:{% tags %}
tag方法 | 介绍 |
---|---|
{% if %} | {% if %}标签计算一个变量值,如果是“true”,即它存在、不为空并且不是false的boolean值,系统则会显示{% if %}和{% endif %}间的所有内容 |
{% for %} | {% for %}标签允许你按顺序遍历一个序列中的各个元素,每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容 |
csrf_token | 用于生成csrf_token的标签,用于防治跨站攻击验证。 其实,这里是会生成一个input标签,和其他表单标签一起提交给后台的。 |
{% url %} | 引用路由配置的地址 |
{% with %} | 用更简单的变量名替代复杂的变量名 |
{% verbatim %} | 禁止render |
{% load %} | … |
加载标签库:自定义filter和simple_tag
注意:
filter可以用在if等语句后,simple_tag不可以
{% if num|filter_multi:30 > 100 %}
{{ num|filter_multi:30 }}
{% endif %}
django.db.backends.sqlite3
django.db.backends.mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'books', #你的数据库名称
'USER': 'root', #你的数据库用户名
'PASSWORD': '', #你的数据库密码
'HOST': '', #你的数据库主机,留空默认为localhost
'PORT': '3306', #你的数据库端口
}
}
import pymysql
pymysql.install_as_MySQLdb()
from app01.models import *
#create方式一: Author.objects.create(name='Alvin')
#create方式二: Author.objects.create(**{"name":"alex"})
#save方式一: author=Author(name="alvin")
author.save()
#save方式二: author=Author()
author.name="alvin"
author.save()
重点:创建存在一对多或多对多关系;处理外键关系的字段如一对多的publisher和多对多的authors
#一对多(ForeignKey):
#方式一: 由于绑定一对多的字段,比如publish,存到数据库中的字段名叫publish_id,所以我们可以直接给这个
# 字段设定对应值:
Book.objects.create(title='php',
publisher_id=2, #这里的2是指为该book对象绑定了Publisher表中id=2的行对象
publication_date='2017-7-7',
price=99)
#方式二:
# <1> 先获取要绑定的Publisher对象:
pub_obj=Publisher(name='河大出版社',address='保定',city='保定',
state_province='河北',country='China',website='http://www.hbu.com')
OR pub_obj=Publisher.objects.get(id=1)
# <2>将 publisher_id=2 改为 publisher=pub_obj
#多对多(ManyToManyField()):
author1=Author.objects.get(id=1)
author2=Author.objects.filter(name='alvin')[0]
book=Book.objects.get(id=1)
book.authors.add(author1,author2)
#等同于:
book.authors.add(*[author1,author2])
book.authors.remove(*[author1,author2])
#-------------------
book=models.Book.objects.filter(id__gt=1)
authors=models.Author.objects.filter(id=1)[0]
authors.book_set.add(*book)
authors.book_set.remove(*book)
#-------------------
book.authors.add(1)
book.authors.remove(1)
authors.book_set.add(1)
authors.book_set.remove(1)
#注意: 如果第三张表是通过models.ManyToManyField()自动创建的,那么绑定关系只有上面一种方式
# 如果第三张表是自己创建的:
class Book2Author(models.Model):
author=models.ForeignKey("Author")
Book= models.ForeignKey("Book")
# 那么就还有一种方式:
author_obj=models.Author.objects.filter(id=2)[0]
book_obj =models.Book.objects.filter(id=3)[0]
s=models.Book2Author.objects.create(author_id=1,Book_id=2)
s.save()
s=models.Book2Author(author=author_obj,Book_id=1)
s.save()
>>> Book.objects.filter(id=1).delete()
(3, {'app01.Book_authors': 2, 'app01.Book': 1})
我们表面上删除了一条信息,实际却删除了三条,因为我们删除的这本书在Book_authors表中有两条相关信息,这种删除方式就是django默认的级联删除。