Django 中提供了开发网站经常用到的模块,常见的代码都为你写好了,通过减少重复的代码,Django 使你能够专注于 web 应用上有 趣的关键性的东西。为了达到这个目标,Django 提供了通用Web开发模式的高度抽象,提供了频繁进行的编程作业的快速解决方法,以及为“如何解决问题”提供了清晰明了的约定。Django的理念是DRY(Don’t Repeat Yourself)来鼓励快速开发!
#linux
django-admin.py startproject project_name
#windows
django-admin startproject project_name
首先进入项目目录下,然后再执行以下命令
python manage.py startapp app_name
#或者
django-admin startapp app_name
新建的 app 要加到 settings.py中的INSTALL_APPS 中,如果不加的话, django 就不能自动找到app中的模板文件(app-name/templates/下的文件)和静态文件(app-name/static/中的文件)
#Django 1.7.1及以上 用以下命令
# 1. 创建更改的文件
python manage.py makemigrations
# 2. 将生成的py文件应用到数据库
python manage.py migrate
#旧版本的Django 1.6及以下用
python manage.py syncdb
这种方法可以在SQL等数据库中创建与models.py代码对应的表,不需要自己手动执行SQL。
备注:对已有的 models 进行修改,Django 1.7之前的版本的Django都是无法自动更改表结构的。
开发服务器,即开发时使用,一般修改代码后会自动重启,方便调试和开发,但是由于性能问题,建议只用来测试,不要用在生产环境。
python manage.py runserver
# 当提示端口被占用的时候,可以用其它端口:
python manage.py runserver 8001
python manage.py runserver 9999
# 监听机器所有可用 ip (电脑可能有多个内网ip或多个外网ip)
python manage.py runserver 0.0.0.0:8000
# 如果是外网或者局域网电脑上可以用其它电脑查看开发服务器
# 访问对应的 ip加端口,比如 http://172.16.20.2:8000
python manage.py flush
python manage.py createsuperuser
# 按照提示输入用户名和对应的密码就好了邮箱可以留空,用户名和密码必填
# 修改 用户密码可以用:
python manage.py changepassword username
python manage.py dumpdata appname > appname.json
python manage.py loaddata appname.json
python manage.py shell
这个命令和 直接运行 python 或 bpython 进入 shell 的区别是:你可以在这个 shell 里面调用当前项目的 models.py 中的 API,对于操作数据,还有一些小测试非常方便。
python manage.py dbshell
Django 会自动进入在settings.py中设置的数据库,如果是 MySQL 或 postgreSQL,会要求输入数据库用户密码。
网址入口,关联到对应的views.py中的一个函数(或者generic类),访问网址就对应一个函数。
Django 1.7.x 及以下
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', 'learn.views.index'), # new
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
)
Django 1.8.x - Django 2.0 版本
from django.conf.urls import url
from django.contrib import admin
from learn import views as learn_views # new
urlpatterns = [
url(r'^$', learn_views.index), # new
url(r'^admin/', admin.site.urls),
]
Django 2.0 版本以上
from django.contrib import admin
from django.urls import path
from learn import views as learn_views # new
urlpatterns = [
path('', learn_views.index), # new
path('admin/', admin.site.urls),
]
处理用户发出的请求,从urls.py中对应过来, 通过渲染templates中的网页可以将显示内容,比如登陆后的用户名,用户请求的数据,输出到网页。
# coding:utf-8
from django.http import HttpResponse
def index(request):
return HttpResponse(u"Hello World")
Django 的设置,配置文件,比如 DEBUG 的开关,静态文件的位置等。
wsgi是python web开发的标准,类似于协议。它是服务器程序和应用程序的一个约定,规定了各自使用的接口和功能,以便二和互相配合。开发时常用uwsgi+ngix。
与数据库操作相关,存入或读取数据时用到这个,当然用不到数据库的时候 你可以不使用。
from django.db import models
# Create your models here.
class UserType(models.Model):
name=models.CharField(max_length=32)
class UserInfo(models.Model):
username=models.CharField(max_length=30)
password=models.CharField(max_length=32)
email=models.CharField(max_length=32)
user_type=models.ForeignKey(UserType,on_delete=models.CASCADE)
#创建表结构后要用命令同步
# Django 1.6.x 及以下
python manage.py syncdb
# Django 1.7 及以上的版本需要用以下命令
python manage.py makemigrations
python manage.py migrate
表单,用户在浏览器上输入数据提交,对数据的验证工作以及输入框的生成等工作,当然你也可以不使用。
views.py 中的函数渲染templates中的Html模板,得到动态内容的网页,当然可以用缓存来提高速度。
后台,可以用很少量的代码就拥有一个强大的后台。
用来管理Django项目。
记录数据修改
配置当前app的。
单元测试。
该目录是用来放一些静态文件,如css.js。
需要在settings.py里添加如下代码
STATICFILES_DIRS=(os.path.join(BASE_DIR,'static'),)
urls.py
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path(r'login',views.login),#将url与view关联,当访问该url跳转到login方法里
path(r'home',views.home)
]
views.py
from django.shortcuts import render
from django.http import HttpResponse
def login(request):
return HttpResponse('Hello World')
在网页上做加减法,访问http://127.0.0.1:8002/add/?a=2&b=1
urls.py
from django.contrib import admin
from django.urls import path
from calc import views as calc_views
urlpatterns = [
path('add/', calc_views.add, name='add'), # new
path('admin/', admin.site.urls),
]
views.py
from django.shortcuts import render
from django.http import HttpResponse
def add(request):
a = request.GET.get('a',0)
b = request.GET.get('b',0)
c = int(a)+int(b)
return HttpResponse(str(c))
采用 /add/3/4/ 这样的网址的方式
urls.py
from django.contrib import admin
from django.urls import path
from calc import views as calc_views
urlpatterns = [
path('add///' , calc_views.add, name='add'), # new
'''name 可以用于在 templates, models, views ……中得到对应的网址,相当于“给网址取了个名字”,只要这 个名字不变,网址变了也能通过名字获取到。
'''
path('admin/', admin.site.urls),
]
Python 代码获取对应的网址
>>> from django.core.urlresolvers import reverse # django 1.4.x - django 1.10.x
或者
>>> from django.urls import reverse # Django 1.10.x - Django 2.x 新的,更加规范了
>>> reverse('add2', args=(4,5))
u'/add/4/5/'
>>> reverse('add2', args=(444,555))
u'/add/444/555/'
Templates中获取网址
不带参数的:
{% url 'name' %}
带参数的:参数可以是变量名
{% url 'name' 参数 %}
例如:
<a href="{% url 'add2' 4 5 %}">linka>
views.py
from django.shortcuts import render
from django.http import HttpResponse
def add(request, a, b):
c = int(a) + int(b)
return HttpResponse(str(c))
网站模板的设计,一般的,我们做网站有一些通用的部分,比如 导航,底部,访问统计代码等等
nav.html, bottom.html, tongji.html
可以写一个 base.html 来包含这些通用文件(include)
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}默认标题{% endblock %} - 自强学堂</title>
</head>
<body>
{% include 'nav.html' %}
{% block content %}
<div>这里是默认内容,所有继承自这个模板的,如果不覆盖就显示这里的默认内容。</div>
{% endblock %}
{% include 'bottom.html' %}
{% include 'tongji.html' %}
</body>
</html>
如果需要,写足够多的 block 以便继承的模板可以重写该部分,include 是包含其它文件的内容,就是把一些网页共用的部分拿出来,重复利用,改动的时候也方便一些,还可以把广告代码放在一个单独的html中,改动也方便一些,在用到的地方include进去。其它的页面继承自 base.html 就好了,继承后的模板也可以在 block 块中 include 其它的模板文件。
比如我们的首页 home.html,继承或者说扩展(extends)原来的 **base.html,**可以简单这样写,重写部分代码(默认值的那一部分不用改)
{% extends 'base.html' %}
{% block title %}欢迎光临首页{% endblock %}
{% block content %}
{% include 'ad.html' %}
这里是首页,欢迎光临
{% endblock %}
Django 模板查找机制:Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码只在当前的 app 的 templates 文件夹中找)。各个 app 的 templates 形成一个文件夹列表,Django 遍历这个列表,一个个文件夹进行查找,当在某一个文件夹找到的时候就停止,所有的都遍历完了还找不到指定的模板的时候就是 Template Not Found (过程类似于Python找包)。这样设计有利当然也有弊,有利是的地方是一个app可以用另一个app的模板文件,弊是有可能会找错了。所以我们使用的时候在 templates 中建立一个 app 同名的文件夹,这样就好了。
这就需要把每个app中的 templates 文件夹中再建一个 app 的名称,仅和该app相关的模板放在 app/templates/app/ 目录下面。
#views.py
# -*- coding: utf-8 -*-
from django.shortcuts import render
def home(request):
string = u"Hello World"
return render(request, 'home.html', {'string': string})
#home.html
{{ string }}
#views.py
# -*- coding: utf-8 -*-
from django.shortcuts import render
def home(request):
list =[1,2,3]
return render(request, 'home.html', {'list': list})
#home.html
{% for i in list %}
{{ i }}
{% endfor %}
#可以用下面来获取list值
{{i.0}}
#当列表中可能为空值时用 for empty
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% empty %}
<li>抱歉,列表为空</li>
{% endfor %}
#views.py
# -*- coding: utf-8 -*-
from django.shortcuts import render
def home(request):
d ={'name':'a','age':'11'}
return render(request, 'home.html', {'d': d})
#home.html
name={{d.name}}
age={{d.age}}
#还可以这样遍历字典
{% for key, value in d.items %}
{{ key }}: {{ value }}
{% endfor %}
{% for item in List %}
{{ item }}{% if not forloop.last %},{% endif %}
{% endfor %}
在for循环中还有很多有用的东西,如下:
变量 | 描述 |
---|---|
forloop.counter |
索引从 1 开始算 |
forloop.counter0 |
索引从 0 开始算 |
forloop.revcounter |
索引从最大长度到 1 |
forloop.revcounter0 |
索引从最大长度到 0 |
forloop.first |
当遍历的元素为第一项时为真 |
forloop.last |
当遍历的元素为最后一项时为真 |
forloop.parentloop |
用在嵌套的 for 循环中,获取上一层 for 循环的 forloop |
# views.py
def add(request, a, b):
c = int(a) + int(b)
return HttpResponse(str(c))
# urls.py
urlpatterns = patterns('',
url(r'^add/(\d+)/(\d+)/$', 'app.views.add', name='add'),
)
# template html
{% url 'add' 4 5 %}
{% url 'some-url-name' arg arg2 as the_url %}
<a href="{{ the_url }}">链接到:{{ the_url }}</a>
#==, !=, >=, <=, >, < 这些比较都可以在模板中使用,and, or, not, in, not in 也可以在模板中使用
{% if var >= 90 %}
成绩优秀,自强学堂你没少去吧!学得不错
{% elif var >= 80 %}
成绩良好
{% elif var >= 70 %}
成绩一般
{% elif var >= 60 %}
需要努力
{% else %}
不及格啊,大哥!多去自强学堂学习啊!
{% endif %}
{% if num <= 100 and num >= 0 %}
num在0到100之间
{% else %}
数值不在范围之内!
{% endif %}
#获取当前用户
{{ request.user }}
#如果登陆就显示内容,不登陆就不显示内容
% if request.user.is_authenticated %}
{{ request.user.username }},您好!
{% else %}
请登陆,这里放登陆链接
{% endif %}
#获取当前网址:
{{ request.path }}
#获取当前 GET 参数:
{{ request.GET.urlencode }}
#合并
<a href="{{ request.path }}?{{ request.GET.urlencode }}&delete=1">当前网址加参数 delete</a>