本文第一章将介绍使用Django开发一个简单的新闻发布网站及其管理后台。最终效果:新闻将显示在网站首页上,并且可以通过管理后台对新闻进行发布、编辑等操作。
在第二章中将介绍如何使用PyCharm进行linux远程开发,通过这个方式可以提高远程开发Django项目的效率。
python3 -m pip install django==2.2
#以下命令将在当前路径下创建名为my_django_news的项目文件夹和初始工程文件
django-admin startproject my_django_news
项目结构与初始工程文件如下:
my_django_news // my_django_news项目文件夹
├── my_django_news // 该项目的一些全局设定
│ ├── __init__.py
│ ├── settings.py // 项目设置
│ ├── urls.py // 网页的路由结构,从哪里可以跳转到哪里
│ └── wsgi.py // WSGI服务相关(本文未用到)
└── manage.py // 通过该脚本传命令参数,可以对项目发送命令
创建项目后,就可以先试着运行起来了
cd my_dango_news
#从现在开始,当如下执行manage.py脚本时,都默认已经处于my_django_news目录下,省略相应cd操作
python3 manage.py runserver
注1:运行后,会在终端上看到红色小字警告,暂时忽略即可,不影响demo运作。
注2:该方法需要在服务主机上使用浏览器访问127.0.0.1:8000才能访问成功。若服务器上没有浏览器,需要使用其他主机进行访问,则需要额外处理,具体方法可参考下一小节。
注3:可以使用一个终端运行django服务,并保持开启,django会自动重新加载变更的代码;然后另开一个终端来运行其他命令。
通过127.0.0.1:8000进行访问,可以看到django的默认界面
已经初步成功了,接下来看看远程访问的方法
修改settings.py中的允许访问主机列表为任意
ALLOWED_HOSTS = ['*']
服务器使用如下命令运行django服务
python3 manage.py runserver 0.0.0.0:8000
开启该服务器端口8000的访问权限
在任意主机浏览器中输入服务器IP地址:8000即可访问,如服务器ip为123.234.12.34,则输入123.234.12.34:8000进行访问
一个Django项目构建的应用由多个子应用组成,这些子应用称为Django App
内置App | 第三方App | 自定义App |
---|---|---|
admin | Django Rest Framework | news(接下来创建这个) |
sessions | Django CORS Headers | |
auth | Django Bootstrap | |
… | … | … |
接下来创建一个名为news的自定义app
python3 manage.py startapp news
执行后,可以看到项目文件夹下新增了一个名为news的文件夹,其结构如下:
news // news自定义app目录
├── __init__.py
├── admin.py // 管理后台的相关配置
├── apps.py // App配置(本文未用到)
├── migrations // 数据库迁移文件目录
│ └── __init__.py
├── models.py // 数据模型
├── tests.py // 单元测试(本文未用到)
└── views.py // 页面视图
可见Django对每个子app中的模块拆分很细,满足MTV模型
MTV模型与MVC模型的关系如下,可以理解为命名上的不同,中心思想是类似的
MTV模型 | MVC模型 | |
---|---|---|
数据模型 | Model | Model |
用户界面 | Template | View |
业务逻辑 | View | Controller |
接下来还需要将news app加到全局配置settings.py中,修改 settings.py 中的INSTALLED_APPS列表,新增一行将news app纳入:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'news', #这里是新增的一行
]
到这里就完成了news app的创建,下文将按照V、T、M的顺序说明Django的MTV模型,并分别实现news app的V、T、M部分,进而实现news应用的部署
在本节,先简单编写一个helloworld视图代码,然后略过,在编写好news应用的template和model代码后,再来升级本节news的view代码。
现在打开全局设定中的urls.py文件(my_django_news/urls.py),可以看到
urlpatterns = [
path('admin/', admin.site.urls),
]
urls.py管理着相应Django页面的路由信息,也就是控制着从当前页面可以跳转到哪里,上面的默认配置意味着可以通过xxx.xxx.xxx.xxx:8000/admin来访问管理后台。
若现在尝试访问此地址,由于还没有登陆任何用户,系统会自动跳转到登陆界面。
打开news/views.py,先试着写一个简单的helloworld视图
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World!')
Django 同时支持FBV(基于函数的视图)和CBV(基于类的视图),这里采用 FBV的方式,接收一个 请求对象参数,返回一个 HttpResponse 对象。实际效果就是显示一串简单的字符串"Hello World"
修改my_django_news/urls.py,使得主页能链接到news的路由表
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('news.urls')), #新增这一行,字符串为空代表当前页面
]
修改news/urls.py,使得news路由能链接到news的view.py中指定的视图
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name = 'index'), #也采用空字符串,意味着不增加跳转,仍然为当前页面
]
通过上面2步,就可以通过主页找到news的路由,而news的路由又会直接找到news的视图。访问xxx.xxx.xxx.xxx:8000,可以看到如下页面
上一节返回了一个简单字符串作为前端页面的显示,这个方法将数据与视图混合在了一起,不符合MTV的思想。这一节将使用Django模板来编写前端页面,使得表现层与数据层分离。
三种常用的模板语法,分别为变量显示、条件语句、循环语句。
本节注释采用方便显示的#形式,实际上Django模板的注释格式为:{# 这是一个Django模板注释 #}
显示变量的值
#单个变量
{{ variable }}
#获取字典的键或对象的属性
{{ dict.key }}
{{ object.attribute }}
#获取列表中的某个元素
{{ list.0 }}
编写模板如下:
<h1>{{ player }}h1>
<p>{{ info.level }}p>
<p>{{ info.item.0 }}p>
并假设往视图中传入以下数据:
{
'player': 'Lux',
'info': {
'level': '99',
'item': ['LGgram15', 'HonorV10'],
}
}
则最终生成的 html 代码为:
<h1>Luxh1>
<p>99p>
<p>LGgram15p>
根据condition变量的真假,进入不同的语句分支。条件语句必须以{% endif %}结束,{% else %}是可选的。
{% if condition %}
<h1>trueh1>
{% else %}
<h1>falseh1>
{% endif %}
从my_list列表中显示每个列表元素ele,必须以{% endfor %}结尾
{% for ele in my_list %}
<p>{{ ele }}p>
{% endfor %}
若my_list数据为 [‘LGgram15’, ‘HonorV10’,‘iPadAir2’],则生成的html代码为:
<p>LGgram15p>
<p>HonorV10p>
<p>iPadAir2p>
在 news 目录下创建 templates 目录,再在 templates 目录下创建一个news 目录,最后在这个内层 news 目录中创建 index.html 文件
mkdir -p news/templates/news #-p参数可以递归创建多层不存在的目录
touch news/templates/news/index.html #使用touch命令快速创建不存在的文件
注:可以只创建 news/templates,然后把 index.html 直接放在该目录下,但由于 Django 的模板查找机制会将所有 app 中 templates 目录下的文件结构全部视为一个全局路径之下,若两个处于不同 app 的 templates 目录下的模板的名字发生冲突,将使其中一个模板不能被正确访问。因此,将 news 的模板放置在 news/templates/news/ 下,这样通过 news/index.html 来访问该模板,以取巧的形式来防止命名冲突。
根据先前提到的Django模板语法,编辑刚刚新建的index.html文件
{% if news_list %}
<ul>
{% for elem in news_list %}
<li>
<h3>{{ elem.title }}h3>
<p>{{ elem.content }}p>
li>
{% endfor %}
ul>
{% else %}
<p>暂无新闻p>
{% endif %}
这样就编写好了news的前端页面模板,接下来讨论数据模型,为模板的实际渲染提供内容
ORM 能够将面向对象的代码自动转换为其对应的 SQL 语句,进而对数据库进行操作。
一些简单的 Django ORM 例子:
# 查询所有模型
# 等价于 SELECT * FROM Comment
Comment.objects.all()
# 查询单个模型
# 等价于 SELECT * FROM Comment WHERE ID=1
Comment.objects.get(id=1)
# 添加单个模型
# 等价于 INSERT INTO Comment (title, content) VALUES ('nice blog', 'very good')
comment = Comment(title='nice blog', content='very good')
comment.save()
数据库迁移是指将 Django 定义的模型转换成对应的 SQL 代码(即迁移文件),并在数据库中进行相应操作(建表或更新表)
一般开发流程:
修改news/models.py文件,定义数据模型Post,包括title字段和content字段
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
def __str__(self):
return self.title
执行如下命令创建迁移文件
python3 manage.py makemigrations
输出如下
Migrations for 'news':
news/migrations/0001_initial.py #表示成功创建了迁移脚本
- Create model Post
接下来执行数据库迁移命令
python3 manage.py migrate
输出如下,注意红框部分
同时可以看到在项目文件夹下生成了一个名为db.sqlite3的文件
执行如下命令创建超级账户,根据提示输入用户名与密码
python3 manage.py createsuperuser
访问xxx.xxx.xxx.xxx:8000/admin,使用刚刚的超级账户进行登录
暂时还看不到刚才创建的news应用和其Post模型,将在下一小节解决
修改news/admin.py,实现news应用的管理后台接口
from django.contrib import admin
from .models import Post
admin.site.register(Post)
刷新一下页面,现在可以看到了
点击Add按钮添加一条新闻,此外,通过Change按钮可以修改或删除新闻
终于到了最后一步,需要升级此前的view代码,把helloworld替换掉,使其可以查询数据库内的新闻内容,修改news/views.py如下
from django.shortcuts import render
from .models import Post
def index(request):
context = { 'news_list': Post.objects.all() }
return render(request, 'news/index.html', context = context)
原先我是在linux环境下直接用vim来写,但是苦于代码补全以及vim下django相关的各种配置都比较麻烦,因而转向使用PyCharm连接linux服务器进行远程开发,简单快捷。
要使用PyCharm的远程开发功能,需要使用PyCharm的专业版,免费的社区版没有这个功能。
在校学生可以申请教育认证来免费使用专业版,只要使用学校邮箱来申请即可,几分钟的事情,十分方便。下列网址为官方的教育认证链接,网址打开比较慢,需要耐心等待:
PyCharm免费教育许可证申请
我申请时写的预期毕业日期为21年6月30日,不过最后证书下来的有效期是到21年4月17日,只有365天,不过也够用了。
上传:由于在此前的远程连接服务器设置中,已经勾选了自动上传,正常来说不需要再手动上传,但有时候由于网络原因自动上传失败,需要在此处进行手动上传。
下载:由于我先在服务器上创建了项目,所以需要在最初的时候进行一次下载,使得本地能够拉取到服务器上已经存在的项目文件。
[1] 一杯茶的时间,上手 Django 框架开发
[2] 使用 PyCharm 远程调试 Django 项目