Django基础和基本使用
Posted Jonathan1314
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django基础和基本使用相关的知识,希望对你有一定的参考价值。
Django基础 |
Django是Python下的一款著名的Web框架
框架
任何语言进入到高级部分时,会有认证、session、http、连接数据库等等功能操作,没有框架时需要自己实现
框架 是整个或部分系统的可重用设计,表现为一组抽象组件及组件实例间交互的方法;
Django优点
-
自带轮子众多,方便快速开发 如Auth,Cache,模板等
-
天生的MVC设计模块
-
实用的后台管理
-
自带ORM,Template,Form,Auth核心组件
-
简洁的url设计
-
周边插件丰富
Django缺点
-
重
-
同步阻塞
和其他Web框架对比
-
Flask:小而精
-
Tornado:基于事件,异步
Django设计哲学
-
大而全
-
快速开发
Django历史
最初开发者:Adrian和Simon
开发背景:World Online维护几个新闻站点,要求快速发布新闻,快速建立其他新闻站点(快速开发,数据驱动)
开源时间:2005年夏天 World Online小组宣布开源
官方网站:https://www.djangoproject.com
文档地址:https://docs.djangoproject.com/en/1.11/
Django安装
使用版本 Django 1.11 Python3.5.2
pip install -i https://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com django python -c "import django; print(django.get_version())"
需求:web页面要求列出最新10本书
Django Model - models.py
用一个Python类来描述数据表,我们称之为模型(model)
运用这个类,你可以通过简单的Python代码来创建、检索、更新、删除数据库中的记录而无需写一条又一条的SQL语句
这就是传说中的ORM(Object Relation Mapping)
# 数据
from django.db import models class Book(models.Model): name = models.CharField(max_length=50) pub_date = models.DateField()
Django View - view.py
View 包含了项目的业务逻辑,我们称之为视图,也是我们开发过程中主要编写的内容
# 算法
from django.shortcuts import render from models import Book def latest_books(request): book_list = Book.objects.order_by(\'-pub_date\')[:10] return render(request, \'latest_books.html\', {\'book_list\': book_list})
Django UrlConf - urls.py
指出了什么样的URL调用什么样的视图,如 /latest/ 调用 latest_books()这个函数
如果你的域名是 example.com,任何人浏览 http://example.com/latest/ 将会调用latest_books()这个函数的返回结果给用户
# 路径
from django.conf.urls import url import views urlpatterns = [ url(r\'^latest/$\', views.latest_books), ]
Django Template
简单来说就是html模板,它描述了项目的界面结构。模板引擎也内置了一些tag
# 前端展示
<ul> {% for book in book_list%} <li>{{ book.name }}</li> {% endfor %} </ul>
基本相应流程
Django基本使用 |
需求:
-
查看所有问题
-
可以让用户投票
-
可以查看投票结果
一 项目 Project
1. 新建项目
django-admin startproject mysite
2. 运行项目
python manage.py runserver 0.0.0.0:8000
-
启动的是django内置的webserver,仅用于开发测试
-
更改py文件后server会自动reload
3. Django项目目录结构
mysite |--manage.py # 管理工具:运行项目、迁移数据 |--mysite # 项目配置信息目录 |--urls # 项目urls入口,分发 |--wsgi # wsgi部署
4. Hello World实现
from django.conf.urls import url from django.contrib import admin from django.http import HttpResponse def index(request): return HttpResponse(\'This is index page\') def hello(request): return HttpResponse(\'Hello World\') urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^$\', index), url(r\'^hello/$\', hello), ]
-
urlpatterns
-
url函数(regex, view, kwargs=None, name=None)
-
注意是view function object而不是执行函数
-
前面的/和 和后面/
-
项目入口 urls
-
request view第一个参数永远是request(不探讨CBV)
-
HttpResponse (view永远返回一个Response对象,显示或隐式)
二 Django App
1. 与project的关系和区别
-
project 公司 app 公司team;project用于配置 app用于实现
-
app中才能使用model
-
app设计是可以插拔的,app不一定在project目录中,app之间尽量不要耦合太多
2. 新建app
python manage.py startapp polls
3. App 目录结构
polls # app目录 |--admin.py # 内置后台管理配置 |--apps # app配置 |--migrations # ORM版本控制,迁移的各类数据 |--models.py # 数据模型定义,只有app才有 |--test.py # 单元测试 |--views.py # app的views函数
4. 项目关联app,配置project settings 导入app
INSTALLED_APPS = [ \'django.contrib.admin\', \'django.contrib.auth\', \'django.contrib.contenttypes\', \'django.contrib.sessions\', \'django.contrib.messages\', \'django.contrib.staticfiles\', \'polls\', ]
5. 编写app view
from django.shortcuts import render, HttpResponse, redirect def index(request): return HttpResponse(\'This is index page\') def hello(request): return HttpResponse(\'Hello World\')
6. 编写urls
app urls 注册到 项目urls中,各app之间项目独立,分发思想
from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^polls/\', include(\'polls.urls\')) ]
polls/urls.py 默认是不存在的,需要创建
from django.conf.urls import url from polls import views urlpatterns = [ url(r\'^$\', views.index), url(r\'^hello/\', views.hello) ]
三 Django 使用数据库
支持的数据库
-
SQLite
-
mysql(MariaDB)
-
PostgreSQL
-
Oracle
设置使用数据库
DATABASES = { \'default\': { \'ENGINE\': \'django.db.backends.mysql\', #数据库引擎 \'NAME\': \'db_name\', #数据库名 \'USER\': \'root\', #用户名 \'PASSWORD\': \'root\', #密码 \'HOST\': \'localhost\', #数据库主机,默认为localhost \'PORT\': \'3306\', #数据库端口,MySQL默认为3306 \'OPTIONS\': { \'autocommit\': True, }, } }
Python 3.5+不支持MySQLdb驱动,可选方案:
-
pymysql,python写的,速度慢,在站点__init__.py文件中,添加代码 import pymysql; pymysql.install_as_MySQLdb()
-
mysqlclient fork的 mysqldb支持python3.3+速度快,官方推荐 https://pypi.python.org/pypi/mysqlclient/
-
在对db没有要求的情况下,postgre或许是个更好的选择 https://docs.djangoproject.com/en/1.11/ref/databases/
编写App models
ORM用python方法、数据结构访问db,不用写SQL
可以兼容不同数据库
# polls/models.py from django.db import models class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField(\'date published\') class Choice(models.Model): question = models.ForeignKey(\'Question\', on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)
说明
-
models.Model 继承父类的属性和方法,继承优势
-
CharField varchar()
-
DateTimeField datetime
-
IntegerField int
-
ForeignKey 一对多关系 question_id
-
on_delete 是否级联删除
-
max_length
-
default
-
blank
-
null
Models Migrate
编写完数据模型需要应用到数据库,Django为了能跟踪表结构的变化,增加了migrations版本控制功能
如果没有该功能,每次表结构发生变化,就需要重新生成表结构,重新导入数据
python manage.py makemigrations
python manage.py migrate
python manage.py shell
-
一个class代表一张表(多对多会产生额外一张关系表)
-
默认主键为id,也可以自定义主键
-
表名默认为 app名称_类名.lower(),可以重写
Models增删改查
增:
q = models.Question(**kwargs)
q.save()
q = models.Question.objects.create(**kwargs)
查:
models.Question.objects.all() # 查询所有 models.Question.objects.filter(question_text="What\'s up?") models.Question.objects.get(id=1)
改:
q = models.Question.objects.get(id=1) q.question_text = "some text" q.save() models.Question.objects.filter(id=1).update(question_text="Why?")
删:
q = models.Question.objects.get(id=1) q.delete() models.Question.objects.get(id=1).delete() models.Question.objects.all().delete()
说明:
-
def __unicode__(self):pass
-
__str__ = __unicode__
-
timezone带来的问题
View中使用Model
需求列出最近5个问题
def index(request): latest_question_list = models.Question.objects.order_by(\'-pub_date\')[:5] output = \',\'.join([q.question_text for q in latest_question_list ]) return HttpResponse(output)
完成详情,提供投票,显示投票结果
# polls/views.py def detail(request, question_id): return HttpResponse(\'You are looking at question {}\'.format(question_id)) def results(request, question_id): return HttpResponse(\'You are looking at results of question {}\'.format(question_id)) def vote(request, question_id): return HttpResponse(\'You are voting on question {}\'.format(question_id)) # polls/urls.py urlpatterns = [ url(r\'^(?P<question_id>[0-9]+)/$\', views.detail, name=\'detail\'), url(r\'^(?P<question_id>[0-9]+)/results/$\', views.results, name=\'results\'), url(r\'^(?P<question_id>[0-9]+)/vote/$\', views.vote, name=\'vote\'), ]
说明
-
(?P<question_id>[0-9]+)---->关键字参数传入views函数中;对应()位置参数形式传入views函数中
-
detail(request, question_id)
-
args, kwargs 总是 字符串
四 模板Template
Django内置了自己的模板引擎,和jinja很像,使用简单
>>> from django.template import Template, Context >>> t = Template("My name is {{ name }}") >>> c = Context({"name":"Jonathan"}) >>> t.render(c)
模板使用变量,小数点新式
-
字典
-
属性
-
方法,无参数
-
列表/元组,list1.0
模板引擎还支持过滤器和循环判断
for循环
{% for person in person_list%} <li>{{ person.name }}</li> {% endfor%}
if判断
{% if max > 10%} <li>最大值 {{ max }}</li> {% else %} <li>最大值10</li> {% endif%}
过滤器,本质函数
{{ now | date:"F j,Y"}} {{ name | length}}
View中使用模板
Django默认会去app/templates下寻找模板,默认会去app/static中寻找静态文件(css, js, jpg)
模板+上下文--->渲染--->HTML文档
version 1:
def index(request): latest_question_list = models.Question.objects.order_by(\'-pub_date\')[:5] template = Template(""" <img src="/static/django.png"> {% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> {% endfor %} </ul> {% endif%} """) context = Context({\'latest_question_list\':latest_question_list}) return HttpResponse(template.render(context))
version 2:
# templates/polls/index.html < img src = "/static/django.png" > { % if latest_question_list %} < ul > { % for question in latest_question_list %} < li > < a href = "/polls/{{ question.id }}/" > {{question.question_text}} < / a > < / li > { % endfor %} < / ul > { % endif %} # polls/views.py from django.template import loader def index(request): latest_question_list = models.Question.objects.order_by(\'-pub_date\')[:5] template = loader.get_template(\'polls/index.html\') context = Context({\'latest_question_list\':latest_question_list}) return HttpResponse(template.render(context))
version 3:
from django.shortcuts import render def index(request): latest_question_list = models.Question.objects.order_by(\'-pub_date\')[:5] context = Context({\'latest_question_list\':latest_question_list}) return render(request, \'polls/index.html\', context)
设置公用 templates和static
TEMPLATES = [ { \'BACKEND\': \'django.template.backends.django.DjangoTemplates\', \'DIRS\': [os.path.join(BASE_DIR, \'templates\')] , \'APP_DIRS\': True, \'OPTIONS\': { \'context_processors\': [ \'django.template.context_processors.debug\', \'django.template.context_processors.request\', \'django.contrib.auth.context_processors.auth\', \'django.contrib.messages.context_processors.messages\', ], }, }, ] STATIC_URL = \'/static/\' STATICFILES_DIRS = ( os.path.join(BASE_DIR, \'static\'), )
去掉url和static硬编码
if、 for、 url 模板默认tag,static 不是,需要{% load static %}
{% load static %} <img src="{% static \'django.png\' %}"> {% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="{% url \'detail\' question.id %}">{{ question.question_text }}</a></li> {% endfor %} </ul> {% endif %}
url 反解析
正解析:url -> view
反解析:view name -> url
说明:
reverse
reverse_lazy
url命名空间
app namespace
定义方法一
# polls/urls.py app_name = \'polls\'
定义方法二
# mysite/urls.py url(r\'^polls/\', include(\'polls.urls\', app_name=\'polls\')
instance namespace
定义
# mysite/urls.py url(r\'^polls/\', include(\'polls.urls\', namespace=\'polls\')
测试
或者
reverse(\'polls:detail\', args(1,))
通常使用app namespace,如果app有多个include,api_urls和view_urls则使用instance namespace
五 form 处理
1. vote页面
# polls/detail.html <h1>{{ question.question_text }}</h1> {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} <form action="{% url \'polls:vote\' question.id %}" method="post"> {% csrf_token %} {% for choice in question.choice_set.all %} <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}"/> <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br/> {% endfor %} <input type="submit" value="Vote"/> </form> 以上是关于Django基础和基本使用的主要内容,如果未能解决你的问题,请参考以下文章html PHP代码片段: - AJAX基本示例:此代码演示了使用PHP和JavaScript实现的基本AJAX功能。