沉淀,再出发:Django的简单使用

一、前言

    在学习了python的基础语法之后,其实大家都很怀疑python的使用场景,其实python在很多场合都有很强的适应性,就比如说web开发之中使用的Django就是用python语言写成的,并且该web框架来开发web应用非常的方便和快捷。

二、Django的简单使用

   对一件新的事物,开始的时候我们没必要了解的很深层次,因为这样反而不利于我们的学习和使用,因此我们就从使用和问题入手来学习Django。

  2.1、安装和使用

   在windows之中首先要安装python,在这里最好使用3.x,这样就顺带安装了pip,因此我们在cmd中,使用pip install Django就可以安装Django了。

   之后我们使用测试版本的命令来看一下是否安装成功,接下来就可以使用了。

   值得称赞的一点就是在Django之中已经自动为我们集成了目录的框架和架构,我们只需要简单地命令就能创建相应的目录结构并且操作。

   我们使用 django-admin.py startproject my_django 来创建一个Django工程,工程名可以自己定义。

 django-admin.py startproject my_django

   可以看到自动创建的工程和文件已经成功了,之后我们需要再创建一个应用app,一般一个项目有多个app, 当然通用的app也可以在多个项目中使用。

 python manage.py startapp app_name
或 django-admin.py startapp app_name

  当然我们还可以创建数据库表:

    并且我们还可以使用开发服务器,便于我们测试,在部署的时候就不能使用了,默认会监听8000端口,如果被占用可以自己定义端口号。

python manage.py runserver
python manage.py runserver 端口

    并且我们可以创建超级管理员,修改密码等。

 python manage.py createsuperuser
# 按照提示输入用户名和对应的密码就好了邮箱可以留空,用户名和密码必填
# 修改 用户密码可以用:
python manage.py changepassword username

    我们还可以查看更多的命令:

python manage.py
E:\my_django>python manage.py

Type 'manage.py help <subcommand>' for help on a specific subcommand.

Available subcommands:

[auth]
changepassword
createsuperuser [contenttypes]
remove_stale_contenttypes [django]
check
compilemessages
createcachetable
dbshell
diffsettings
dumpdata
flush
inspectdb
loaddata
makemessages
makemigrations
migrate
sendtestemail
shell
showmigrations
sqlflush
sqlmigrate
sqlsequencereset
squashmigrations
startapp
startproject
test
testserver [sessions]
clearsessions [staticfiles]
collectstatic
findstatic
runserver

2.2、运行任务(视图与网址)

   如果我们仔细观察目录的结构就会发现其实Django运用了我们熟悉的类似于mvc的框架来开发,因此对于我们来说修改起来很方便。我们只需要修改视图文件views和网址文件urls就可以将前端的访问进行对应并且处理了,可以暂时这样理解,urls文件接收到用户的请求之后,根据对应的关系,找到相应的视图文件对应的函数,来将请求进行处理并返回结果给前端。因此,我们先来修改视图文件views,在文件中加入一个响应函数,名称可以自己定义,第一个参数就是request请求的参数,返回字符串给前端。注意编码要进行修改。

 # coding:utf-8
from django.shortcuts import render
from django.http import HttpResponse def index(request):
return HttpResponse(u"hello,world!")

   之后我们修改urls文件,注意将views所在的包引入其中,并且添加对应关系:

    之后我们运行服务器接收任务:

    可以看到成功执行任务,貌似没有什么问题,但是,我们还是要注意把我们新定义的app加到settings.py中的INSTALL_APPS中, 新建的 app 如果不加到 INSTALL_APPS 中的话, django 就不自动找到app中的模板文件(app_name/templates/下的文件)和静态文件(app_name/static/中的文件) ,这在我们现在没用到的时候就要养成好的习惯。
修改 mysite/mysite/settings.py:

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'my_app'
]

    如果只是达到这种程度的对应,我们无法处理更加复杂的url请求,比如传统的url后面带参数的请求,以及restful的请求,那么Django能否做到呢,答案是肯定的。

def add_1(request):
a = request.GET['a']
b = request.GET['b']
c = int(a)+int(b)
return HttpResponse(str(c))
 path('add_1/', my_views.add_1, name='add_1'),

   可以看到成功接收请求并且处理成功了,那么在urls文件中的name代表什么呢,其实就是代表的网址对应的标识,简单说name 可以用于在 templates, models, views ……中得到对应的网址,相当于“给网址取了个名字”,只要这个名字不变,网址变了也能通过名字获取到。同样的对于restful方式的代码如下:

def add_2(request, a, b):
c = int(a) + int(b)
return HttpResponse(str(c))
path('add_2/<int:a>/<int:b>/', my_views.add_2, name='add_2'),

2.3、关于urls文件中name的解释

     name对应了一个网址,在代码中我们习惯用name来代表网址进行代码的编写,这样的好处在于,当我们的网址发生改变的时候,只需要在urls之中进行更改即可,不需要将所有用到这个网址的地方(比如模板,html文件等)都做修改了,为了说明这一点我们看一个例子:

<!DOCTYPE html>
<html>
<head>
<title>name的作用</title>
</head>
<body> <a href="/add_2/4/5/">计算 4+5</a> </body>
</html>

  新建上面的文件命名为:myhome.html,在app中新建模板文件夹templates,将该文件放入其中:

   之后修改views和urls文件:

   但是如果我们以后想要修改path('add_2/<int:a>/<int:b>/', my_views.add_2, name='add_2'),中的'add_2/<int:a>/<int:b>/'为'add_new/<int:a>/<int:b>/'的时候,我们的html代码也需要跟着改,但是如果使用这个url的地方有很多,是非常苦恼的一件事情,因此我们不建议在HTML中<a href="/add_2/4/5/">计算 4+5</a>编程。

   下面我们修改HTML:

<a href="{% url 'add_2' 4 5 %}">计算4+5</a>

   修改urls:

   再次访问可以看到无论网址如何变化,使用name绑定,只要name不变就能正确解析,而在编程之中name最好不要改变,因此这样就能保证只修改url就能使得程序正常工作了。

2.4、Django模板的使用

   模板这个词语在很多的语言之中都有使用,同样的在前端的页面渲染之中,模板的用处就更多了,比如nodejs中的ejs容器等等,模板的作用就是承载着数据的传递,数据绑定和界面的呈递。同样的在Django之中,也有模板的概念,一般情况下都是将三剑客之中的HTML作为模板的承载器,因为HTML是展示给用户看的。

  同样的,我们创建项目:,记得将app加入到setting文件之中,这样我们在app文件夹之下新建文件夹templates,在其中加入一个HTML文件(home.html):

 <!DOCTYPE html>
<html>
<head>
<title>欢迎光临</title>
</head>
<body>
{{ string }}
</body>
</html>

然后我们修改views文件,加入处理事件,同样的修改urls文件,添加对应关系:

 def home(request):
string = u"用Django建网站"
return render(request, 'home.html', {'string': string})
 from django.contrib import admin
from django.urls import path
from learn import views as learn_views urlpatterns = [
path('', learn_views.home, name='home'),
path('admin/', admin.site.urls),
]

  然后运行开发服务器,访问网页,查看结果:

   虽然样例很小,但是意义重大,因为我们使用Django完成了第一个数据绑定的例子,可以看到我们是在模板之中,使用了{{ 变量名 }}来表示一个变量,然后在views层,我们将该变量传递进入其中,这样我们就完成了数据的绑定。

   同样的我们还可以进行更加复杂的数据绑定:

 from django.shortcuts import render

 def home(request):
string = u"用Django建网站"
return render(request, 'home.html', {'string': string}) def sec(request):
myList = ["HTML", "CSS", "jQuery", "Python", "Django"]
return render(request, 'home.html', {'myList': myList}) def third(request):
info_dict = {'site': u'zyr_web', 'content': u'各种IT技术教程'}
return render(request, 'home.html', {'info_dict': info_dict})
 from django.contrib import admin
from django.urls import path
from learn import views as learn_views urlpatterns = [
path('', learn_views.home, name='home'),
path('admin/', admin.site.urls),
path('sec/', learn_views.sec, name='sec'),
path('third/', learn_views.third, name='third'),
]
 <!DOCTYPE html>
<html>
<head>
</head>
<body>
{{ string }} <br>
教程列表:
{% for i in myList %}
{{ i }}
{% endfor %} <br>
站点:{{ info_dict.site }} 内容:{{ info_dict.content }} <br>
<p>显示词典内容:</p>
{% for key, value in info_dict.items %}
{{ key }}: {{ value }}
{% endfor %}
</body>
</html>

  模板中for循环的使用:

 在for循环中还有很多有用的东西,如下:
forloop.counter 索引从 1 开始算
forloop.counter0 索引从 0 开始算
forloop.revcounter 索引从最大长度到 1
forloop.revcounter0 索引从最大长度到 0
forloop.first 当遍历的元素为第一项时为真
forloop.last 当遍历的元素为最后一项时为真
forloop.parentloop 用在嵌套的 for 循环中,获取上一层 for 循环的 forloop
def forth(request):
List = map(str, range(100))
return render(request, 'home.html', {'List': List})
    path('forth/', learn_views.forth, name='forth'),
{% for item in List %}
{{ item }}{% if not forloop.last %},{% endif %}
{% endfor %}

 模板中的逻辑操作:
   ==, !=, >=, <=, >, < 这些比较都可以在模板中使用,注意:比较符号前后必须有至少一个空格,比如:

{% if var >= 90 %}
成绩优秀,学得不错
{% elif var >= 80 %}
成绩良好
{% elif var >= 70 %}
成绩一般
{% elif var >= 60 %}
需要努力
{% else %}
不及格啊,大哥!
{% endif %}

  and, or, not, in, not in 也可以在模板中使用,假如我们判断 num 是不是在 0 到 100 之间:

{% if num <= 100 and num >= 0 %}
num在0到100之间
{% else %}
数值不在范围之内!
{% endif %}

2.5、上下文渲染器

    有时候我们想让一些内容在多个模板中都要有,比如导航内容,我们又不想每个视图函数都写一次这些变量内容,怎么办呢?这时候就可以用 Django 上下文渲染器来解决。上下文渲染器 其实就是函数返回字典,字典的 keys 可以用在模板中。
    我们在项目自动生成的主目录下(与settings.py 在一起)新建一个 context_processor.py

#!/usr/bin/env python
# -*- coding: utf-8 -*- from django.conf import settings as original_settings def settings(request):
return {'settings': original_settings} def ip_address(request):
return {'ip_address': request.META['REMOTE_ADDR']}

    之后我们把新建的两个上下文渲染器 加入到 settings.py 中

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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', 'django_tmpl.context_processor.settings',
'django_tmpl.context_processor.ip_address'
,
],
},
},
]

   然后在模板文件夹下面新建文件夹和两个文件:

  修改views文件:

 def index(reuqest):
return render(reuqest, 'myblog/index.html') def columns(request):
return render(request, 'myblog/columns.html')

   修改urls文件:

    path('blog_home/', learn_views.index, name='index'),
path('blog_columns/', learn_views.columns, name='columns'),

   然后我们访问:

    这样我们可以看到在一个文件中的变量(ip),我们可以在多个模板之中使用了,这是非常方便的,如果是在以前,我们需要从views之中绑定变量,但是每一次都需要这样做是非常麻烦的,现在我们通过上下文渲染的方式,直接将这些全局变量放到一个文件之中统一维护,非常的方便和快捷,我们可以直接拿来使用,不用考虑到底是来自什么地方了。

    理解到这一点,我们同样可以通过上下文渲染的方式来获得当前访问的用户等信息,其实这些设置,Django已经帮我们设置好了,在'django.template.context_processors.request'之中。

   于是我们可以直接使用:

<h1>Blog Columns</h1>
<br>
DEBUG: {{ settings.DEBUG }}
<br>
ip: {{ ip_address }}
<br>
setting: {{ settings }}
<br>
当前用户:{{ request.user }}
<br>
当前网址:{{ request.path }}
<br>
当前get参数:{{ request.GET.urlencode }}
<br> <a href="{{ request.path }}?{{ request.GET.urlencode }}&delete=1">当前网址加参数 delete</a>

2.6、数据库操作

我们新建一个应用:

  将我们新建的应用(people)添加到 settings.py 中的 INSTALLED_APPS中。

  我们打开 people/models.py 文件,修改其中的代码如下:

 from django.db import models

 class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField()

   创建数据表,我们来同步一下数据库(我们使用默认的数据库 SQLite3,无需配置):

python manage.py makemigrations
python manage.py migrate

python manage.py shell

from people.models import Person
Person.objects.create(name="zyr", age=25)

    可以看到我们查询的结果不能出来真正的信息,于是我们修改models:

 from django.db import models

 class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField() def __str__(self):
return self.name

   重新运行:

 新建一个对象的方法有以下几种:
a、Person.objects.create(name=name,age=age)
b、p = Person(name="xx", age=23)
p.save()
c、p = Person(name="xx")
p.age = 23
p.save()
d、Person.objects.get_or_create(name="xx", age=23)
这种方法是防止重复很好的方法,但是速度要相对慢些,返回一个元组,第一个为Person对象,第二个为True或False, 新建时返回的是True, 已经存在时返回False. 获取对象有以下方法:
Person.objects.all()
Person.objects.all()[:10] 切片操作,获取10个人,不支持负索引,切片可以节约内存
Person.objects.get(name=name)
get是用来获取一个对象的,如果需要获取满足条件的一些人,就要用到filter
Person.objects.filter(name="abc") # 等于Person.objects.filter(name__exact="abc") 名称严格等于 "abc" 的人
Person.objects.filter(name__iexact="abc") # 名称为 abc 但是不区分大小写,可以找到 ABC, Abc, aBC,这些都符合条件
Person.objects.filter(name__contains="abc") # 名称中包含 "abc"的人
Person.objects.filter(name__icontains="abc") #名称中包含 "abc",且abc不区分大小写
Person.objects.filter(name__regex="^abc") # 正则表达式查询
Person.objects.filter(name__iregex="^abc") # 正则表达式不区分大小写 filter是找出满足条件的,当然也有排除符合某条件的
Person.objects.exclude(name__contains="xx") # 排除包含 xx 的Person对象
Person.objects.filter(name__contains="abc").exclude(age=23) # 找出名称含有abc, 但是排除年龄是23岁的
 删除对象:
Person.objects.filter(name__contains="abc").delete() # 删除 名称中包含 "abc"的人
如果写成
people = Person.objects.filter(name__contains="abc")
people.delete()
效果也是一样的,Django实际只执行一条 SQL 语句
更新对象:
(1) 批量更新,适用于 .all() .filter() .exclude() 等后面 (危险操作,正式场合操作务必谨慎)
Person.objects.filter(name__contains="abc").update(name='xxx') # 名称中包含 "abc"的人 都改成 xxx
Person.objects.all().delete() # 删除所有 Person 记录
(2) 单个 object 更新,适合于 .get(), get_or_create(), update_or_create() 等得到的 obj,和新建很类似。
myobj= Author.objects.get(name="xxx")
myobj.name="xxxx"
myobj.email="xxxx@163.com"
myobj.save() # 最后不要忘了保存!!!

2.7、Django后台

   首先我们还是新建一个app,然后将该app注入到setting之中,注意我们在更新数据库之后要设置管理员用户名和密码:

  在新建的app下面的models之中加入:

# coding:utf-8
from django.db import models class Article(models.Model):
title = models.CharField(u'标题', max_length=256)
content = models.TextField(u'内容') pub_date = models.DateTimeField(u'发表时间', auto_now_add=True, editable = True)
update_time = models.DateTimeField(u'更新时间',auto_now=True, null=True)

  在新建app目录的下面的admin文件(如果没有,新建一个)之中注册该models:

 from django.contrib import admin
from .models import Article # Register your models here. admin.site.register(Article)

   因为该admin文件的入口,我们已经在urls之中打开了:

  因此我们直接访问:

  可以看到我们已经有了一个强大的Django后台了,我们可以在articles之中添加对象:

但是此时文章没有区分性,我们继续修改models文件:

 # coding:utf-8
from django.db import models class Article(models.Model):
title = models.CharField(u'标题', max_length=256)
content = models.TextField(u'内容') pub_date = models.DateTimeField(u'发表时间', auto_now_add=True, editable = True)
update_time = models.DateTimeField(u'更新时间',auto_now=True, null=True) def __str__(self):
return self.title

   此时就能看到文章的标题了:

我们还可以继续修改,使得后台更加的完善:

from django.contrib import admin
from .models import Article # Register your models here. class ArticleAdmin(admin.ModelAdmin):
list_display = ('title','pub_date','update_time',) admin.site.register(Article,ArticleAdmin)

三、总结

    关于Django我们算是有了基本的了解了,知道了models,views,urls的相关配置以及相应的写法,并且知道了数据库的增删改查,模板的相关使用,参数绑定,循环分支语句,知道了Django后台的相关功能,上下文渲染的相关知识等等,对我们的编程非常有利,作为一个后端的web框架,Django非常的轻量级,在真正的工程开发中,往往是采用BVDN的开发方式(Bootstrap+VUE+Django+Nginx)来进行全栈开发的。

参考文献:https://code.ziqiangxuetang.com/django/django-tutorial.html

沉淀,再出发:Django的简单使用的更多相关文章

  1. 沉淀再出发:在python3中导入自定义的包

    沉淀再出发:在python3中导入自定义的包 一.前言 在python中如果要使用自己的定义的包,还是有一些需要注意的事项的,这里简单记录一下. 二.在python3中导入自定义的包 2.1.什么是模 ...

  2. 沉淀再出发:java中的equals()辨析

    沉淀再出发:java中的equals()辨析 一.前言 关于java中的equals,我们可能非常奇怪,在Object中定义了这个函数,其他的很多类中都重载了它,导致了我们对于辨析其中的内涵有了混淆, ...

  3. 沉淀再出发:web服务器和应用服务器之间的区别和联系

    沉淀再出发:web服务器和应用服务器之间的区别和联系 一.前言 关于后端,我们一般有三种服务器(当然还有文件服务器等),Web服务器,应用程序服务器和数据库服务器,其中前面两个的概念已经非常模糊了,但 ...

  4. 沉淀再出发:jetty的架构和本质

    沉淀再出发:jetty的架构和本质 一.前言 我们在使用Tomcat的时候,总是会想到jetty,这两者的合理选用是和我们项目的类型和大小息息相关的,Tomcat属于比较重量级的容器,通过很多的容器层 ...

  5. 沉淀再出发:dubbo的基本原理和应用实例

    沉淀再出发:dubbo的基本原理和应用实例 一.前言 阿里开发的dubbo作为服务治理的工具,在分布式开发中有着重要的意义,这里我们主要专注于dubbo的架构,基本原理以及在Windows下面开发出来 ...

  6. 沉淀再出发:OpenStack初探

    沉淀再出发:OpenStack初探 一.前言 OpenStack是IaaS的一种平台,通过各种虚拟化来提供服务.我们主要看一下OpenStack的基本概念和相应的使用方式. 二.OpenStack的框 ...

  7. 沉淀再出发:Spring的架构理解

    沉淀再出发:Spring的架构理解 一.前言 在Spring之前使用的EJB框架太庞大和重量级了,开发成本很高,由此spring应运而生.关于Spring,学过java的人基本上都会慢慢接触到,并且在 ...

  8. 沉淀再出发:关于IntelliJ IDEA使用的一些总结

    沉淀再出发:关于IntelliJ IDEA使用的一些总结 一.前言 在使用IDEA的时候我们会发现,如果我们先写了一个类的名字,而没有导入这个类的出处,就会提示出错,但是不能自动加入,非常的苦恼,并且 ...

  9. 沉淀再出发:spring boot的理解

    沉淀再出发:spring boot的理解 一.前言 关于spring boot,我们肯定听过了很多遍了,其实最本质的东西就是COC(convention over configuration),将各种 ...

  10. 沉淀再出发:Bean,JavaBean,POJO,VO,PO,EJB等名词的异同

    沉淀再出发:Bean,JavaBean,POJO,VO,PO,EJB等名词的异同 一.前言 想必大家都有这样的困惑,接触的东西越多却越来越混乱了,这个时候就要进行对比和深入的探讨了,抓住每一个概念背后 ...

随机推荐

  1. ubuntu18.04 安装docker

    https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce-1Change "stable" ...

  2. 关于js语法(运算中出现无限大的问题)本身的错误的解决方案

    错误原因: 一是 JavaScript 浮点数计算的 Bug, 另一个是和计算机最终转换成二进制计算有关系 解决方案: 第一种就是利用JavaScript 的toFixed(n) 方法,直接获取N 位 ...

  3. MapReduce原理——分而治之

    一.MapReduce简介 二.MapReduce并行处理的基本过程 三.MapReduce实际处理流程 四.一个job的运行流程 一.MapReduce简介 MapReduce是一种并行可扩展计算模 ...

  4. InnoDB的视图

    视图(View)是一个命名的虚表,它由一个查询来定义,可以当做表使用.与持久表(permanent table)不同的是,视图中的数据没有物理表现形式. 视图的作用 视图在数据库中发挥着重要的作用.视 ...

  5. [转]如何配置Log4Net使用Oracle数据库记录日志

    本文转自:http://www.cnblogs.com/PatrickLiu/p/6012153.html 最近在做一个项目的时候,需要增加一个日志的功能,需要使用Log4Net记录日志,把数据插入到 ...

  6. Jquery Ajax 复杂json对象提交到WebService

    在ajax的已不请求中,常常返回json对象.可以利用json.net给我们提供的api达到快速开发. 例子: using System;using System.Collections;using ...

  7. SQL Server 两个时间段的差and时间截取到时分

    /*--------------------------时间截取到时分-----------------------------------*/ ), ),)--返回2017-11-24 19:25 ...

  8. .NET MVC自定义Html辅助方法

    using System;using System.Web.Mvc;using System.Web.Routing; namespace MvcTest2.Helpers{ public stati ...

  9. 一、window下zookeeper独立部署

    zookeeper是一个分布式协调应用,用于管理大型主机.通俗地说,分布式应用相对于单体应用存在着很多要处理的问题,而这些问题通常是不太好处理的.比如,典型的一致性问题,而zookeeper可以很简单 ...

  10. 令人头疼的Connection Reset

    背景: 要爬取某网站的数据,数据每页10条,有很多页(形式如同table表格).使用HttpClient 逐行逐页爬取数据,但在循环爬取多次时,总会在不确定的位置报错 在检查代码逻辑无果之后,开始疯狂 ...