Django基础和基本使用

it2026-01-26  9

 

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> # polls/view.py from django.shortcuts import render, get_object_or_404, reverse from django.http import HttpResponseRedirect, HttpResponse from polls import models def vote(request, question_id): question = get_object_or_404(models.Question, pk=question_id) if request.method == 'POST': choice_id = request.POST.get('choice', 0) try: selected_choice = question.choice_set.get(pk=choice_id) except models.Choice.DoesNotExist: return render(request, 'polls/detail.html',{ 'question': question, 'error_message': "没有选择选项" }) else: selected_choice.votes += 1 selected_choice.save() return HttpResponseRedirect(reverse('polls:results', args=(question.id,))) elif request.method == 'GET': return render(request, 'polls/detail.html',{ 'question': question, 'error_message': None })

说明:

request.POST 取用户form表单提交的数据;兼容request.GET

csrf_token  每个表单生成一个标识值,中间件验证

request.FILES  取文件

request.GET

models.Choice.DoesNotExist  继承了models.Model;或导入DoesNotExist类

HttpResponseRedirect   快捷键 redirect

get_object_or_404

get_list_or_404

request

  MEAT, HTTP_REFERER,  HTTP_USER_AGENT, REMOTE_ADDR

  schema, method, COOKIES, FILES

  path, get_host, get_full_path, is_secure

2.  results 页面

# polls/views.py from django.shortcuts import render, get_object_or_404 def results(request, question_id): question = get_object_or_404(models.Question, pk=question_id) return render(request, 'polls/results.html',{'question': question}) # polls/results.html <h1>{{ question.question_text }}</h1> <ul> {% for choice in question.choice_set.all %} <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes| pluralize }}</li> {% endfor %} </ul> <a href="{% url 'polls:vote' question.id %}">Vote again?</a>

 

转载于:https://www.cnblogs.com/jonathan1314/p/7453480.html

相关资源:Django基础知识与基本应用入门教程
最新回复(0)