Cyrus Flag

flag{S0_bangbang_7ha7_u_f1nd_h3r3}

2小时入门Django·简明指南

0x00 一些前提

  • 有Python使用基础
  • 不一定有数据库操作基础(本文使用sqlite)
  • 不限于Python2或者Python3
  • 不限于操作系统(熟练你的操作系统即可,本文以MacOS/Linux为例)
    如果满足上述前提,你可以在2-3hr内看完本文,一步步完成Django框架的基础学习,并且搭建出一个有数据库的基础的展示网页。
    本文遵循黑箱使用原则,最小程度的涉及底层的工作原理。
    本文参考了:https://tutorial.djangogirls.org/zh/
    详细中文文档参见:https://www.gitbook.com/book/wizardforcel/django-chinese-docs-18/details

0x01 安装和开始工作

安装:

1
pip install django

更多系统的安装方式参见:https://tutorial.djangogirls.org/zh/django_installation/ ,btw你可以暂时忽略其中关于虚拟环境的部分。
可以使用以下命令确认是否安装成功:

1
2
import django
django.get_cersion()

在bash中直接创建项目:

1
django-admin.py startproject mystie

在创建mysite目录之后,进入目录创建APP:

1
2
cd mysite
python manage.py startapp blog

以及一些额外的步骤:

  • settings.pyINSTALLED_APPS中增加一个:'blog'
  • settings.py中将时区更改为:TIME_ZONE = 'Asia/Shanghai'
  • settings.py中也可以配置DATABASE。本文用默认的sqlite。
    至此已完成准备工作。

0x02 建立模型

和大多数使用MVC架构的后端框架一样,Django拥有自己的模型管理机制。在每个APP中允许有多个模型。
blog/models.py中,编写以下参考代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from django.db import models
from django.utils import timezone
class Tag(models.Model):
name = models.CharField(max_length=16)
desc = models.TextField(default='This is a tag.')
def __str__(self):
return self.name
class Post(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=64)
tag = models.ForeignKey('Tag')
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now())
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title

说几个重点:

  • 导入的models一行,这里使用自带的sqlite,其他数据库方法不相同。
  • ForeignKey可以引用别的model中的表数据或者同model中别的class的表数据。后台管理页面中会显示为一个下拉菜单。
  • __str__是返回的默认字段。就是当返回为一个Object的时候,显示为“Object\<__str__>”
    之后我们建立网站后台样例。在admin.py中编写以下代码:
    1
    2
    3
    4
    5
    from django.contrib import admin
    from .models import Tag
    from .models import Post
    admin.site.register(Tag)
    admin.site.register(Post)

然后尝试运行一下!在此之前我们先新建一个超级用户,在mysite目录下执行:

1
python manage.py createsuperuser

按提示创建即可。之后使用命令执行:

1
2
3
python manage.py makemigrations blog
python manage.py migrate
python manage.py runserver

进入http://127.0.0.1:8000可以看到一个Django的欢迎页面,进入http://127.0.0.1:8000/admin可以进入一个登录页,用刚才的账户登录,and have fun~

  • 提示:除了更改Step4中的.html文件外,更改一切.py文件均要使用以上三行代码来运行APP。

0x03 视图管理

下面说View部分。
blog/views.py中,编写以下参考代码:

1
2
3
4
5
6
7
8
9
10
11
from django.shortcuts import render
from .models import Post
from django.utils import timezone
def problem(request):
#此处为post相关的内容,写代码时在尝试写一个题库,所以叫做problem了
postlist = Post.objects.filter(published_date__lte=timezone.now()).
posts = postlist.order_by('published_date')
return render(request, 'ctf/problem.html', {'posts': posts})
def detail(request, pk):
posts = Post.objects.get(pk=pk)
return render(request, 'ctf/detail.html', {'posts': posts})

还是几个重点:

  • 导入的Post就是上一步写的model。
  • detail中多了参数pk,在HTML中调用时会传入该参数。
  • render中的页面请新建在blog/templates中。

0x04 前端视图

本文同样提供了problem.htmldetail.html的参考代码:
problem.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CTF</title>
</head>
<body>
<h1>Problem List</h1>
{% for i in posts %}
<h3>{{i}}</h3>
<p>Time: {{i.published_date}}</p>
<p>Tag: {{i.tag}}</p>
<p><a href="{ % url 'detail' pk=i.pk % }">View More >></a></p>
{% endfor %}
</body>
</html>

detail.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{posts.title}}</title>
</head>
<body>
<h1>{{posts.title}}</h1>
<p>Author: {{posts.author}}</p>
<p>Tag: {{posts.tag}}</p>
<p>Time: {{posts.published_date}}</p>
<p></p>
<p>{{posts.text}}</p>
</body>
</html>

其中{ % url 'detail' pk=i.pk % }为调用detail函数传参的方式。
注:{ 和 % 之间没有空格,为了避开这个辣鸡 Hexo 的渲染而已。

0x05 URL管理

我们在项目目录(不是APP目录)中看到了urls.py。这就是Django的URL管理模块。
在其中urlpatterns中追加以下参考代码:

1
url(r'', include('blog.urls'))

注意要从django.conf.urls中导入include
之后在APP目录中建立urls.py的文件,编写以下参考代码:

1
2
3
4
5
6
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.problem, name='problem'),
url(r'^post/(?P<pk>[0-9]+)/$', views.detail, name='detail')
]

这一段比较好理解,不再划重点了。正则表达式的知识不在本文介绍范围内。

0x06 更多内容

回头看下Step2中的运行代码,你可以运行这个APP了!
本文为了尽快把这个APP运行起来,选择性跳过了以下内容:

  • MYSQL数据库的接入
  • CSS的使用(虽然应该不算后端)
  • 模板扩展
  • Django的表单使用
  • 以及更多没有遇见的问题
    将会在下一次介绍。