python3之Django基础篇
一、Django基础
Django 是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网站!
Django的特点:
强大的数据库功能:拥有强大的数据库操作接口(QuerySet API),也能执行原生SQL
自带强大后台:网站拥有一个强大的后台,轻松管理内容
优雅的网址:用正则匹配网址,传递到对应函数,随意定义。
模版系统:易扩展的模版系统,设计简易,代码,样式 分开设计,更容易管理。
缓存系统:与memcached,redis等缓存系统联用,更出色的表现,更快的加载速度。
国际化:完全支持多国语言应用,允许定义翻译的字符,轻松翻译成不同国际的语言。
Django目录结构:
urls.py:网址入口,关联到对应的Views.py中的一个函数,访问网址对应的函数。
views.py:处理用户发出的请求,从urls.py中对应过来,通过渲染templates中的网页可以将显示内容,比如登陆后的用户名,数据,输出到网页。
models.py:与数据库操作相关,存入或读取数据时用到这个
templates文件夹:views.py中的函数渲染templates中的HTML模版,得到动态内容网页,可以用缓存来提高速度。
admin.py:后台,可以用很少量的代码就拥有一个强大的后台。
settings.py:Django的全局设置,配置文件,比如DEBUG的开关,静态文件的位置设置等。
二、Django安装
1、用pip来安装
(1)安装pip:yum install python-pip 或者https://bootstrap.pypa.io/get-pip.py 下载get-pip然后运行python get-pip.py就可以安装pip了;也可以下载pip源码包,运行python setup.py install 进行安装。
(2)利用pip安装Django
pip install Django 或者 pip install Django==2.0.4
升级pip可以用:pip install --upgrade pip
2、下载源码安装
linux and MAC:
下载源码包:https://www.djangoproject.com/m/releases/2.0/Django-2.0.4.tar.gz
tar -xvf django-2.0.4.tar.gz cd django-2.0.4 python setup.py install
3、linux用自带源进行安装
ubuntu: sudo apt-get install python-django -y fedora: yum install python-django -y
检查是否安装成功:看到版本号则安装成功!
In [1]: import django In [2]: django.VERSION Out[2]: (2, 0, 4, 'final', 0) In [3]: django.get_version() Out[3]: '2.0.4'
三、Django基本命令
1、新建一个django project项目
(zhang) [root@python zhang]# django-admin startproject pyqi (zhang) [root@python zhang]# tree pyqi/ pyqi/ ├── manage.py └── pyqi ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py 1 directory, 5 files
pyqi/根目录只是项目的容器,它的名字与Django无关,可以将它重命名为任何任何名字
manage.py:一个命令行实用程序,可让你以各种方式与Django项目进行交互
pyqi:是项目的实际python包,它的名字是你需要用来导入任何内容的python包名
__init__.py:一个空文件,告诉python这个目录应该被视为一个python包
settings.py:这是Django项目的设置与配置,Django设置会告诉你有关设置如何工作的所有信息
urls.py:这是Django项目的URL声明
wsqi.py:WSGI兼容的Web服务器为你的项目提供服务的入口点
2、新建app
cd project_name #切换到项目目录下
python manage.py startapp app_name
或者
django-admin.py startapp app-name
3、创建数据库表或更改数据库表或字段
在APP的models中建立类数据模版 class userinfo(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=32) salary = models.IntegerField() 生成配置文件: (zhang) [root@python pyqi]# python manage.py makemigrations Migrations for 'app01': app01/migrations/0001_initial.py - Create model userinfo 根据配置文件粗昂居数据库相关表: (zhang) [root@python pyqi]# python manage.py migrate Operations to perform: Apply all migrations: admin, app01, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying app01.0001_initial... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying sessions.0001_initial... OK
这种方法可以在SQL等数据库中创建与models代码相对应的表。
4、开发服务器使用
python manage.py runserver 0.0.0.0:8000
5、清空数据库
python manage.py flush
此命令会把数据全部清空掉,只留下空表
6、创建超级管理员
python manage.py createsuperuser
根据提示输入用户名、邮箱和密码,邮箱可以为空
python manage.py changepassword username
修改用户密码
7、导出数据和导入数据
导出数据: python manage.py dumpdata appname > appname.json 导入数据: python manage.py loaddata appname.json
8、更多命令
项目环境终端:
python manage.py shell
数据库命令行:
python manage.py dbshell
查看命令:
python manage.py
四、项目视图、网址、URL、模块、模型
1、新建一个项目
(zhang) [root@python zhang]# django-admin startproject mysite
我们会发现执行命令后,新建了一个 mysite 目录,其中还有一个 mysite 目录,这个子目录 mysite 中是一些项目的设置 settings.py 文件,总的urls配置文件 urls.py 以及部署服务器时用到的 wsgi.py 文件, __init__.py 是python包的目录结构必须的,与调用有关。
2、新建一个应用(app),名称叫leran
(zhang) [root@python mysite]# python manage.py startapp learn (zhang) [root@python mysite]# tree learn/ learn/ ├── admin.py ├── apps.py ├── __init__.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py 1 directory, 7 files
把我们新定义的app加到settings.py中的INSTALL_APPS中
修改 mysite/mysite/settings.py
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'learn', )
新建的 app 如果不加到 INSTALL_APPS 中的话, django 就不能自动找到app中的模板文件(app-name/templates/下的文件)和静态文件(app-name/static/中的文件)
3、定义视图函数(访问页面时的内容)
我们在learn这个目录中,把views.py打开,修改其中的源代码,改成下面的:
from django.shortcuts import render from django.shortcuts import HttpResponse # Create your views here. def index(request): return HttpResponse('ok')
引入HttpResponse,它是用来向网页返回内容的,就像python中的print一样,只不过HttpResponse是把内容显示在网页上。
定义一个index()函数,第一个参数必须是request,与网页发来的请求有关,request变量里面包含get或post内容,用户浏览,系统信息在里面。函数返回一个HttpResponse对象,可以经过一些处理,最终显示在网页上。
render将返回模版
4、定义视图函数相关的URL(地址)即规定访问什么网址对应什么内容。
打开 mysite/mysite/urls.py 这个文件, 修改其中的代码:
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 版本,urls.py 有比较大的变化(上面 Django 1.8 的在 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), ]
该path()传递四个参数,其中两个是必需的:route和view,以及两个可选的:kwargs和name。
route是一个包含UR模式的字符串,在处理请求时,Django从第一个模式开始url patterns并在列表中向下,将所请求的URL与每个模式进行比较,直到找到匹配的模式。
模式不搜索get和post参数或域名,URLconf将查找myapp/
view:当Django找到一个匹配的模式时,它会以一个HttpRequest对象作为第一个参数以及路由中的任何捕获值作为关键字参数来调用指定的视图函数。
kwargs:任意关键字参数可以在字典中传递给目标视图。
name:命名你的URL可以让你从Django其他地方明确的引用它,特别是在模版中,这个强大的功能允许你在只触摸单个文件的情况下对项目的URL模式进行全局更改。
在终端上运行python manage.py runserver运行开发服务器。
python manage.py runserver 0.0.0.0:8000 #表示监听所有地址在8000端口 Performing system checks... System check identified no issues (0 silenced). You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. April 26, 2018 - 05:38:33 Django version 2.0.4, using settings 'mysite.settings' Starting development server at http://0.0.0.0:8000/ Quit the server with CONTROL-C.
访问网址:http://192.168.146.129:8000/ 显示OK就成功了!
5、在网页上使用get方法传参
新建应用app: (zhang) [root@python mysite]# python manage.py startapp calc 修改calc/views.py文件: from django.shortcuts import render from django.http import HttpResponse # Create your views here. def add(request): a = request.GET['a'] b = request.GET['b'] c = int(a)+int(b) return HttpResponse(str(c)) 接着修改 mystie/urls.py 文件,添加一个网址来对应我们刚才新建的视图函数 from django.contrib import admin from django.urls import path from learn import views as learn_views from calc import views as valc_views #增加的行 urlpatterns = [ path('admin/', admin.site.urls), path('',learn_views.index), path('add',calc_views.add,name='add'), #改动的行 ]
访问网址并传值a=8&b=6,页面显示14则表示配置正确:
http://192.168.146.129:8000/add?a=8&b=6
6、采用/add/3/4方式传参
修改calc/views.py文件,定义新函数add2:
def add2(request,a,b): c = int(a) + int(b) return HttpResponse(str(c))
修改urls.py添加URL路由:
path('add/<int:a>/<int:b>/',calc_views.add2,name='add2'),
Django 1.8也可以这样写:
url(r'^add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
访问:http://192.168.146.129:8000/add/1024/768/ 页面显示结果!!!
7、URL详解
url(r'^add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),这里的name=add2'是用来干什么的呢?
简单说,name可以用于在templates,models,views中得到对应的网址,相当于‘给网址取了个名字’,只要这个名字不变
网址变了也能通过名字获取到。
修改calc/views.py 使用render的时候,Django 会自动找到 INSTALLED_APPS 中列出的各个 app 下的 templates 中的文件
def index(request): return render(request,'home.html')
在calc 这个 app 中新建一个 templates 文件夹,在templates中新建一个 home.html
文件 calc/templates/home.html 中写入以下内容(保存时用 utf8 编码)
<!DOCTYPE html> <html> <head> <title>Django 2.0</title> </head> <body> <a href="/add/4/5/">计算 4+5</a> </body> </html>
修改urls.py
path('',calc_views.index,name='home'),
这样写,就把网址写死了,如需修改,代价会很大。
我们可以用python代码获取对应的网址(可以用在views.py,models.py等各种需要转换得到网址的地方)
# python manage.py shell
In [1]: from django.urls import reverse
In [4]: reverse('add2', args=(3,4))
Out[4]: '/add/3/4/'
In [5]: reverse('add2', args=(111,789))
Out[5]: '/add/111/789/
reverse 接收 url 中的 name 作为第一个参数,我们在代码中就可以通过 reverse() 来获取对应的网址(这个网址可以用来跳转,也可以用来计算相关页面的地址),只要对应的 url 的name不改,就不用改代码中的网址。
在网页模板中也是一样,可以很方便的使用
不带参数的: {% url 'name' %} 带参数的:参数可以是变量名 {% url 'name' 参数 %} 例如: <a href="{% url 'add2' 4 5 %}">link</a> 上面的代码渲染成最终的页面是: <a href="/add/4/5/">link</a>
这样就可以通过 {% url 'add2' 4 5 %} 获取到对应的网址 /add/4/5
当对urls进行更改后,前提是不改name,获取的网址也会动态的跟着变。
如URL更改后,需要写个跳转到原来的url上:
def old_to_new(request,a,b): return HttpResponseRedirect( reverse('add2',args=(a,b)) )
8、django模版(templates)
使用模块:在views中使用render渲染网页文件:
from django.shortcuts import render # Create your views here. def index_home(request): return render(request,'t2.html')
在templates目录下建模版文件‘t2.html’,即可实现模版访问!!!
网站模版的设计,一般网站有一些通用的部分,比如:导航,底部,访问统计代码等等。
可以设置分页模版:top.html, bottom.html,
<!DOCTYPE html> <html> <head> <title>{% block title %}不继承标题{% endblock %}</title> </head> <body> {% include 'nav.html' %} #继承nav.html内容 {% block content %} #不继承内容 <div>这里是默认内容,所有继承自这个模板的,如果不覆盖就显示这里的默认内容。</div> {% endblock %} {% include 'bottom.html' %} #继承bottom.html内容 </body> </html>
如果需要,写足够多的 block 以便继承的模板可以重写该部分,include 是包含其它文件的内容,就是把一些网页共用的部分拿出来,重复利用,改动的时候也方便一些,还可以把广告代码放在一个单独的html中,改动也方便一些,在用到的地方include进去。
还可以使用extends来扩展现在网页的内容:
{% extends 'base.html' %} #扩展内容
{% block title %}huanyinguanlin{% endblock %}
{% block content %}
{% include 't3.html' %} #包含内容
{% endblock %}
实例1:基本字符串网页显示
views.py
def test(request): string = "zixuejianzhan" return render(request,'test.html',{'string':string})
home.html
<body> {{ string }} </body>
实例2:list列表在网页中显示
views.py
def list1(request): TutorialList = [1, 5555, "jQuery", "Python", "Django"] return render(request, 'list.html', {'List': TutorialList})
home.html
<body> 教程列表: {% for i in List %} {{ i }} {% endfor %} </body>
实例3:字典在网页中显示
views.py
def dict(request):
info_dict = {'one':'zixue','two':'IT'}
return render(request,'dict.html',{'info_dict':info_dict})
home.html
<body> {{ info_dict.one }}:{{ info_dict.two }} #取字典值 {% for key,value in info_dict.items %} #循环取键值对 {{ key }}: {{ value }} {% endfor %} </body>
实例4:for循环和添加判断
forloop.last判断是否为最后一个元素,不是加‘,’,是则不加
views.py
def forif(request): list = map(str,range(100)) return render(request,'forif.html',{'list':list})
home.html
<body> {% for item in list %} {{ item }}{% if not forloop.last %},{% endif %} {% endfor %} </body>
在for循环中还有很多有用的东西,如下:
forloop.counter 索引从1开始算
forloop.counter0 索引从0开始算
forloop.revcounter 索引从最大长度到1
forloop.revcounter0 索引从最大长度到0
forloop.first 当遍历的元素为第一项时为真
forloop.last 当遍历的元素为最后一项时为真
forloop.parentloop 用来嵌套的for循环中,获取上一层for循环的forloop
当列表中可能为空值时用 for empty:
<ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% empty %} <li>抱歉,列表为空</li> {% endfor %} </ul>
实例5:模块上得到视图对应的网址
#views.py from django.shortcuts import HttpResponse def add(request,a,b): c = int(a) + int(b) return HttpResponse(str(c)) #urls.py from app01 import views as app01_views urlpatterns = [ path('admin/', admin.site.urls), re_path('adds/(\d+)/(\d+)/',app01_views.add,name='add') ] #template.html <body> {% url 'add' 4 5 %} </body>
这样在修改路由后,name会记录网址,在不修改模板的情况下,依然能正常访问网址!
实例6:模板中的逻辑操作(==,!=,>=,<=,>,<)
views.py def home(request,a): return render(request,'home.html',{'a':int(a)}) urls.py re_path('home/(\d+)/',app01_views.home) home.html <body> {{ a }} <br /> {% if a >= 90 %} 成绩优秀! {% elif a >= 80 %} 成绩良好 {% elif a >= 70 %} 成绩一般 {% elif a >= 60 %} 需要努力 {% else %} 不及格,大哥,需要努力了! {% endif %} </body>
注意:比较符号前后必须有至少一个空格!
and,or,not,in,not in也可以在模板中使用
获取当前用户:{{request.user}}
获取当前网址:{{request.path}}
获取当前GET参数:{{request.GET.urlencode}}
完整的内容参考官方文档:https://docs.djangoproject.com/en/1.11/ref/templates/builtins/
五、Django模型(数据库)
Django 模型是与数据库相关的,与数据库相关的代码一般写在 models.py 中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,只需要在settings.py中配置即可,不用更改models.py中的代码,丰富的API极大的方便了使用。
1、在项目应用中的models.py文件中新建类,用来创建数据表
from django.db import models # Create your models here. class person(models.Model): name = models.CharField(max_length=32) age = models.IntegerField()
2、进入项目下使用命令行模式同步数据库(默认使用SQLite3,无需配置)
C:\Users\Administrator\PycharmProjects\untitled\test_django>python manage.py makemigrations Migrations for 'app01': app01\migrations\0001_initial.py - Create model person C:\Users\Administrator\PycharmProjects\untitled\test_django>python manage.py migrate Operations to perform: Apply all migrations: admin, app01, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying app01.0001_initial... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying sessions.0001_initial... OK
我们会看到,Django生成了一系列的表,也生成了我们新建的app01_person这个表
在项目应用中views.py上引导models,创建数据库连接函数:
from app01 import models #数据库连接操作 #创建请求函数通过model下的类链接数据库增加修改数据: def homes(request): #增加数据 方法1: models.userinfo.objects.create(name='zhang',age=9) 方法2: lis={'name':'lisi','password':'1111','age':28} models.userinfo.objects.create(**lis) #删除数据 models.userinfo.objects.filter(name='san').delete() #修改数据 models.userinfo.objects.filter(name='zhang').update(age=23) models.userinfo.objects.all().update(Salary=56789) #修改所有的数据 #查找数据 #models.userinfo.objects.all() #models.userinfo.objects.all()[:10] 切片操作,获取10个数据,不支持负索引 #models.userinfo.objects.filter(name='zhang') #models.userinfo.objects.filter(name='zhang').first() 获取第一个
参考文档:
更多相关内容:http://code.ziqiangxuetang.com/django/django-queryset-api.html
Django models 官方教程: https://docs.djangoproject.com/en/dev/topics/db/models/
Fields相关官方文档:https://docs.djangoproject.com/en/dev/ref/models/fields/
Django数据库操作官方文档: QuerySet API: https://docs.djangoproject.com/en/dev/ref/models/querysets/