Django学习笔记一---入门篇 - Go语言中文社区

Django学习笔记一---入门篇


前言

Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。

正文

环境

系统 : ubuntu 17.10
python : 3.6
Django2.0

Python的虚拟环境virtualenv

为了考虑依赖性问题,将使用virtualenv来搭建对应的环境
安装:

pip install virtualenv

创建虚拟环境

cd project_name_dir
virtualenv venv #venv为虚拟环境的目录名,可以自定义

创建虚拟环境可以指定Python解释器

virtualenv -p python3

or

virtualenv -p /usr/bin/python3.6 env

在这里插入图片描述
要开始使用虚拟环境,需要激活

source env/bin/activate

需要退回系统默认环境或者暂停当前的虚拟环境可以使用以下的命令

deactivate

删除虚拟环境,只需要删除上面新建的目录即可。

安装Django

默认安装的是最后发布的版本

pip install Django

如果需要
指定安装的版本需要下面的命令,比如指定安装版本为2.0的Django。

pip install Django==2.0

在这里插入图片描述

第一个项目Helloworld

创建项目的命令:

django-admin startproject mysite1

然后会在当前目录中新建一个目录,目录结构为:

mysite1
├── manage.py
└── mysite1
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

其中的settings.py为整个Django项目的配置文件,urls.py整个项目的路由控制文件,wsgi.py项目部署使用到的文件。
项目运行流程:
在这里插入图片描述
具体步骤:

  1. 在mysite1/mysite2新建一个名为views.py的文件,内容为
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello world")
  1. 修改urls.py文件,添加一项路由
from django.contrib import admin
from django.urls import path
from . import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", views.index)
]

其中的""代表根目录,如果需要指定路径为test,可以把""修改为test/
3. 回到项目的根目录,运行项目

python3 manage.py runserver

默认是8000端口如果需要指定端口可以使用下面的命令

python3 manage.py runserver 8888

如果需要外网访问当前的项目,可以使用下面的命令

python3 manage.py runserver 0.0.0.0:8888
  1. 运行结果
    在这里插入图片描述

正常的运行流程:

进来的请求转入’/’.
Django通过在ROOT_URLCONF配置来决定根URLconf.
Django在URLconf中的所有URL模式中,查找第一个匹配’/'的条目。
如果找到匹配,将调用相应的视图函数
视图函数返回一个HttpResponse
Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来

Django 自带的后台

urls.py文件中,发现一条url匹配规则path('admin/', admin.site.urls),这条路由规则匹配的是admin后台,访问127.0.0.1/admin出现界面
在这里插入图片描述
然后我们需要创建一个管理员账号,步骤如下:

  1. 迁移数据库–migrate
    使用命令python3 manage.py help可以查看基本的命令
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

如果没有迁移数据库直接使用命令python3 manage.py createsuperuser创建管理员用户会爆出这样的错误

django.db.utils.OperationalError: no such table: auth_user

所以需要先迁移数据库,使用以下的命令迁移数据库,Django默认使用的数据库是sqlite3,可以在settings中更换。

python3 manage.py migrate

在这里插入图片描述

  1. 创建管理员账号–createsuperuser
python3 manage.py createsuperuser

然后输入对应的管理员用户名和邮箱以及密码,ok。因为我设置的密码是123456789,所以出现密码过弱的提示。
在这里插入图片描述

  1. 登录后台
    使用刚刚创建的用户登录,默认的语言是英文,需要修改为中文的话在settings.py中的LANGUAGE_CODE = 'en-us'修改LANGUAGE_CODE = 'zh-hans'
    在这里插入图片描述
    需要修改的:
    在这里插入图片描述
    在这里插入图片描述
    中文后台
    在这里插入图片描述

小结:
启动服务使用命令runserver,迁移(同步)数据库使用命令migrate,创建管理管理员账号使用命令createsuperuser,查看帮助使用命令help

Django 基本应用结构

创建一个新的应用(app) : python3 startapp app_name

首先创建一个Django应用,名为article,创建应用之后还需要在settings.py中声明应用

python3 manage.py startapp article

声明应用,在settings中对应的列表(INSTALLED_APPS)中添加应用名
在这里插入图片描述
此时的目录结构变成了

├── article
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── db.sqlite3
├── manage.py
└── mysite1
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-36.pyc
    │   ├── settings.cpython-36.pyc
    │   ├── urls.cpython-36.pyc
    │   ├── views.cpython-36.pyc
    │   └── wsgi.cpython-36.pyc
    ├── settings.py
    ├── urls.py
    ├── views.py
    └── wsgi.py
  • 其中新建应用中的article/models.py的作用类似于持久层,可在这里面声明模型类,现在修改models.py文件为:
from django.db import models

# Create your models here.
class Article(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()

接着使用命令makemigrations制造迁移,使用命令migrate完成迁移。
在这里插入图片描述
进入打开数据库,发现如果没有指定主键,Django会自动生成pkey
在这里插入图片描述

  • article/admin.py 可以在这里面声明模型类,使其可在admin界面操作
    在admin.py中引入上面创建的模型类Article.py,并注册
    在这里插入图片描述
from django.contrib import admin
from .models import Article
# Register your models here.
admin.site.register(Article)

回到后台,刷新之后出现Article选项,
在这里插入图片描述
并且可以完成增删改查等等操作
在这里插入图片描述

小结:
新建一个应用使用命令python3 manage.py startapp app_name,使用命令python3 manage.py makemigrations完成数据迁移的制造,之后再使用命令python3 manage.py migrate完成数据迁移,迁移的数据生成文件在应用目录下的migrations目录下。在应用中的models.py声明模型类,在admin.py文件中修改后台。

Django使用模板文件

  • 首先学习在url中传递参数,比如传递文章的id
    在article中的views.py文件中添加下面的内容
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.

def article_detail(request, article_id):
    return HttpResponse("文章id为:%s"%article_id

在引入对应的方法然后添加路由
在这里插入图片描述
其中的<int:article_id>代表article_id是一个整型数据,参数名称必须和article_detail方法的参数名一致。
在这里插入图片描述

  • 通过模型获取数据库内容

首先在admin后台向article中添加多条数据
在这里插入图片描述
把article/views.py修改为

from django.shortcuts import render
from django.http import HttpResponse
from .models import Article
# Create your views here.

def article_detail(request, article_id):
    article = Article.objects.get(id=article_id)
    return HttpResponse("文章title为:%s"%article.title)

在这里插入图片描述
当然也可以同时显示文章标题和文章内容,article/views.py内容

from django.shortcuts import render
from django.http import HttpResponse
from .models import Article
# Create your views here.

def article_detail(request, article_id):
    article = Article.objects.get(id=article_id)
    return HttpResponse("文章title为:%s<br>文章的内容为:%s"%(article.title, article.content))

在这里插入图片描述
当访问的id超出数据库中id范围会返回一个DoesNotExist异常
在这里插入图片描述
为了程序的健壮性需要在article/views.py处理异常,一般情况下返回404

from django.shortcuts import render
from django.http import HttpResponse
from .models import Article
# Create your views here.

def article_detail(request, article_id):
    try:
        article = Article.objects.get(id=article_id)
    except Article.DoesNotExist as e:
        return HttpResponse("404")
    return HttpResponse("文章title为:%s<br>文章的内容为:%s"%(article.title, article.content))

在这里插入图片描述
Django中提供了get_object_or_404方法,如果对象不为空返回对象,对象不存在返回404异常。

from django.shortcuts import get_object_or_404
...
blog = get_object_or_404(Blog,pk=blog_pk)
  • 使用模板文件
    上面的写法脚本和静态html完全的混淆到一起,耦合度高,Django提供一种使用模板的方法
from django.shortcuts import render
from django.http import HttpResponse
from .models import Article
# Create your views here.

def article_detail(request, article_id):
    try:
        article = Article.objects.get(id=article_id)
        context = {}
        context["article_obj"] = article
        return render(request, "article_detail.html", context)
    except Exception as e:
        raise

并且在article应用的根目录中新建一个目录template,这个目录中存放html模板文件。例如新建一个模板文件为article_detail.html,内容为:

<html>
    <head>
        <title>article_detail</title>
    </head>
    <body>
        <h3>{{article_obj.title}}</h3>
        <p>{{article_obj.content}}</p>
    </body>
</html>

其中的render(request, "article_detail.html", context)方法一共有三个参数,第一个为request:存放与请求相关的信息,第二个"article_detail.html"为使用的模板文件名称,第三个context则是存放模板所需要的参数字典对象。与render方法相类似的方法还有render_to_response("article_detail.html", context)主要参数只有两个模板文件名和参数字典,request对象会自动传过去。
而在模板文件中使用到脚本传过来的参数的使用方法是{{参数字典对象.参数的key}}

而在django.shortcuts模块中还有一个非常常用的方法get_object_or_404,如果存在对象返回对象,否则返回404.可以精简代码。
精简后的article/views代码

from django.shortcuts import render, render_to_response, get_object_or_404
from django.http import HttpResponse
from .models import Article
# Create your views here.

def article_detail(request, article_id):
    article = get_object_or_404(Article, id=article_id)
    context = {}
    context["article_obj"] = article
    #return render(request, "article_detail.html", context)
    return render_to_response("article_detail.html", context)

在这里插入图片描述

  • locals()函数的妙用
    locals()函数的返回值:返回字典类型的局部变量。
In [1]: def test_locals(var):
   ...:     a = 1
   ...:     print(locals())
   ...:     
In [2]: test_locals(2)
{'a': 1, 'var': 2}

locals()函数的特性可以在views视图中使用
比如存在这样的一个视图方法

def current_datetime(request):
    now = datetime.datetime.now()
    return render_to_response('current_datetime.html', {'current_date': now})

我们可以利用locals函数进行偷懒,但是这个偷懒的方法是有代价的,在下面例子中locals()还包含request

def current_datetime(request):
    current_date = datetime.datetime.now()
    return render_to_response('current_datetime.html', locals())
```requestrequest
- 模板文件的for循环,类似的还用if
现在写一个文章列表界面,首先需要在article/views.py中添加一个方法`article_list(request)`
```python
def article_list(request):
    articles = Article.objects.all()
    context = {}
    context["articles"] = articles
    return render(request, "artilce_list.html", context)

然后修改路由配置,添加一项配置

path("article/", article_list),

然后在article/templates中新增加一个模板article_list.html

<html>
    <head>
        <title>article_list page</title>
    </head>
    <body>
        {%for article in articles%}
            <a href="/article/{{article.id}}">{{article.title}}</a><br>
        {%endfor%}
    </body>
</html>

其中{{article.id}}可以修改为{{article.pk}},pk即是主键的缩写,建议使用{{article.pk}}
在这里插入图片描述

  • 分路由文件–urls.py
    如果整个项目的urls都配置在同一个配置文件的话,将很难维护,Django提供了一种分路的方法,可以在每一个应用中新建一个urls.py文件,在这个文件中配置好路由信息之后,再在主的路由配置文件中通过include包含子路由配置文件的内容。即是在urls.py文件中注释代码的第三种配置方法
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))

详细步骤:

  1. 在应用目录article/下新建一个urls.py文件
from django.urls import path
from .views import article_detail, article_list

urlpatterns = [
    path("<int:article_id>", article_detail),
    path("", article_list),
]
  1. 修改主的urls.py为
from django.contrib import admin
from django.urls import path, include
from . import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path("test/", views.index),
    path("article/", include("article.urls"))
]

url命名空间

在真正的Django项目中,可能有五个,十个,二十个应用程序或更多。Django如何区分它们之间的URL名称?例如,polls应用程序有一个detail 视图,因此同一项目中的应用程序可能适用于博客。如何使Django知道在使用模板标签时为url创建哪个应用视图 ?{% url %}

答案是为URLconf添加名称空间。在polls/urls.py 文件中,继续并添加一个app_name以设置应用程序命名空间:

#urls.py
from django.urls import path
from . import views
app_name = 'polls'  # 命名空间
urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
    path('<int:question_id>/results/', views.results, name='results'),
    path('<int:question_id>/vote/', views.vote, name='vote'),
]

在模板中使用命名空间

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

定制后台和修改模型

定制后台

问题描述:进入后台之后发现字段名显示的是Article object (1),更加合理的应该是显示文章的标题。
在这里插入图片描述
解决方法:在对应的models类中添加对应的__str__()方法并且返回对应的字段。

from django.db import models
# Create your models here.
class Article(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()
    def __str__(self):
        return self.title

运行结果
在这里插入图片描述
如果需要显示多个字段的话,则需要修改对应应用中的admin.py

from django.contrib import admin
from .models import Article
# Register your models here.
class ArticleAdmin(admin.ModelAdmin):#增加实现admin.ModelAdmin的类
    list_display = ("id", "title", "content")
admin.site.register(Article, ArticleAdmin)#增加对应的admin类

运行效果(此时的id为逆序)
在这里插入图片描述
因为默认排序为逆序,假如需要自定义排序的方法需要在admin类中添加ording

from django.contrib import admin
from .models import Article
# Register your models here.
class ArticleAdmin(admin.ModelAdmin):
    list_display = ("id", "title", "content")
    ordering = ("id",) # id正序排序,注意是元祖不是括号
admin.site.register(Article, ArticleAdmin)

需要逆序的话(默认):ordering = ("-id",)
同时可以装饰器来装饰admin定制类

from django.contrib import admin
from .models import Article
# Register your models here.
@admin.register(Article) # 增加的admin装饰器,代码清晰很多了
class ArticleAdmin(admin.ModelAdmin):
    list_display = ("id", "title", "content")
    ordering = ("-id",)
admin.site.register(Article, ArticleAdmin)

修改模型

问题描述:在一开始模型设计时可能出现问题,或者是业务需求的改变,需要向数据库中增加一些字段,比如前面创建的article的model举例,models中只有标题和内容,现在我们需要向里面增加一个字段:创建文章的时间(create_data)

步骤:

  1. 修改models.py文件增加对应的字段,添加一个字段创建文章的时间
from django.db import models

# Create your models here.
class Article(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()
    create_data = models.DateTimeField(auto_now__add=True) ## 新增的字段
    def __str__(self):
        return self.title

重新运行之后,刷新界面报错
在这里插入图片描述
之后执行制造迁移(makemigrations),和迁移(migrate)即可,在admin.py增加显示的项目,效果
在这里插入图片描述

继续修改models.py文件,添加最后更新时间

from django.db import models

# Create your models here.
class Article(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()
    create_date = models.DateTimeField(auto_now_add=True)
    last_update_date = models.DateTimeField(auto_now=True)
    def __str__(self):
        return self.title

其中的DateTimeField的参数auto_now_add适合用在功能类似创建时间字段中,他的时间只会自动生成一次。而DateTimeField的参数设置为auto_now则适合在更新时间字段,每一次执行的更新数据库操作都会更新时间。
在这里插入图片描述

常见的还有设置外键models.ForeignKey等等

模板相关

常见的模板标签

用两个括号括起来的文字(例如{{person_name}})称为变量.此处插入指定变量的值.
用大括号和百分号包围的文字(例如{%if xxxxx%})被称为模板标签.标签(tag)定义比较明确,即: 仅通知模板系统完成某些工作的标签。模板标签一般都有结束标签比如if的结束标签是{%endif%}

  • {%url name%}标签

一般最简单的设置url的方法这这样的

{% for blog in blogs%}
	<h3><a href="blog/{{blog.pk}}">{{blog.title}}</a></h3>
{%endfor%}

Django还提供一个url标签,首先在urls.py文件设置url时需要设置一个路由的别名

urlpatterns = [
    path("", blog_list, name = "home"),
]

接着在模板文件中可以使用url标签调用对应的url

<a href="{%url 'home'%}">

结果和下面的方法一样,但是建议使用url标签

<a> href="/"</a>
  • {%for%}和{%empty%}标签
    {%for%}标签的用法和Python中的for循环的用法类似
    {%empty%}标签主要使用在当传过来的对象集合为空时输出的内容或者执行的动作,必须配合for循环使用。
{% for blog in blogs%}
	<h3><a href="blog/{{blog.pk}}">{{blog.title}}</a></h3>
	{% empty %}
		<p>暂时没有博客</p>
{%endfor%}

当内容不为空时直接输出内容
在这里插入图片描述

进入后台把文章全部删除之后,刷新页面
在这里插入图片描述
给标签增加一个 reversed 使得该列表被反向迭代:

{% for athlete in athlete_list reversed %}
...
{% endfor %}

Django不支持退出循环操作。 如果我们想退出循环,可以改变正在迭代的变量,让其仅仅包含需要迭代的项目。 同理,Django也不支持continue语句,我们无法让当前迭代操作跳回到循环头部。

在每个{% for %}循环里有一个称为forloop 的模板变量。这个变量有一些提示循环进度信息的属性。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/huanghelouzi/article/details/84069131
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢