系统:Ubuntu16.04
Python版本:python3.5.2
一、建立虚拟环境
要使用Django,首先需要建立一个虚拟工作环境。虚拟环境是系统中的一个位置,你可以在其中安装包,并将其与其他Python包隔离。
将项目的库与其他项目分离是有益的。
安装virtualenv,终端运行
sudo apt-get install python-virtualenv
为项目新建一个目录,将其命名为learning_log,并在终端切换到目录learning_log,创建一个虚拟环境:
virtualenv ll_env --python=python3
如图:
激活虚拟环境:
source ll_env/bin/activate
如图:
环境处于活动状态时,环境名将包含在括号内。
关闭虚拟环境:
deactivate
安装Django
(ll_env) czz@xcy-laptop:~/PycharmProjects/Project_3/learning_log$ pip install Django
在Django中创建项目(需在虚拟环境下):最后的句点千万别忘了
django-admin startproject learning_log .
如图:
创建数据库:
python manage.py migrate
查看项目:
python manage.py runserver
将会 有如下输出:
Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). April 20, 2019 - 08:10:02 Django version 2.2, using settings 'learning_log.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
打开浏览器,并输入URL:http://127.0.0.1:8000/出现下面的页面:
这是最新版的Django的默认启动界面。暂且不要关闭它。
二、创建应用程序
前面打开的终端窗口应该还运行着runserver,再打开一个终端窗口,并切换到manage.py所在的目录,激活虚拟环境并执行命令
python manage.py startapp learning_logs
定义模型:
打开models.py 添加
from django.db import models # Create your models here. class Topic(models.Model): """用户学习的主题""" text = models.CharField(max_length=200)#由字符或文本组成的数据 date_added = models.DateTimeField(auto_now_add=True)#记录日期和时间的数据 def _str_(self): """返回模型的字符串表示""" return self.text
创建了一个Topic类,它继承了Model。
激活模型:
打开learning_log/learning_logs/settings.py,将前面的程序添加到这个元组中
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', #我的应用程序,以上都是自带的,Django2.0这样添加 'learning_logs.apps.LearningLogsConfig', ]
在终端依次输入
python manage.py makemigrations learning_logs
python manage.py migrate
每当需要修改“学习笔记”管理的数据时,都采取如下三个步骤:修改model.py;对learning_logs调用makemigrations;让Django迁移项目。
创建超级用户:终端输入(虚拟环境下)
python manage.py createsuperuser
依提示输入用户名、密码,邮箱可以不填(Enter)
向管理网站注册模型,在learning_logs中找到admin.py,打开并修改:
from django.contrib import admin # Register your models here. #导入模型Topic from learning_logs.models import Topic #注册 admin.site.register(Topic)
终端执行命令,运行Django服务器:
python manage.py runserver
访问http://localhost:8000/admin/,输入用户名和密码,可见:
手动添加主题,单击Topic,进入表单,使用add添加主题Chess和Rocking Climbing
定义模型Entry:条目,多个条目可关联同一主题
打开models.py
-----snip------ class Entry(models.Model): "学到的有关某个主题的具体知识" #外键,数据库术语,将每个条目关联到特定的主题 topic = models.ForeignKey(Topic, on_delete=models.CASCADE) #条目文本 text = models.TextField() #时间戳 date_added = models.DateTimeField(auto_now_add=True) #嵌套类Meta,它用于管理模型的额外信息。它让我们能够设置一个特殊属性,让Django在需要时 # 使用Entries来表示多个条目。如果没有这个类,Django将使用Entrys来表示多个条目,保证英语语法正确 class Meta: verbose_name_plural = 'entries' #呈现条目时应显示的信息 def _str_(self): "返回模型的字符串表示" return self.text[:50] + '...'
迁移模型Entry,终端输入:
python manage.py makemigrations learning_logs
python manage.py migrate
向网站注册Entry,修改admin.py文件
from django.contrib import admin # Register your models here. #导入模型Topic from learning_logs.models import Topic, Entry #注册 admin.site.register(Topic) admin.site.register(Entry)
以上还是老三步:修改model.py;对learning_logs调用makemigrations;让Django迁移项目,然后在admin.py文件注册Entry。
接下来就可以添加条目了,在Chess中添加了一个条目,就不细写了。
Django Shell
输入一些数据后,可通过交互式终端会话以编程方式查看这些数据。这种交互式环境称为Django shell,是测试项目和排除故障的理想之地。
(ll_env)learning_log$ python manage.py shell # 启动shell >>> from learning_logs.models import Topic >>> Topic.objects.all() # 获得模型Topic的所有实例 <QuerySet [<Topic: Chess>, <Topic: Rock Climbing>]> # 返回了一个查询集QuerySet >>> topics = Topic.objects.all() # 查询每个Topic对象 >>> for topic in topics: ... print(topic.id, topic) ... 1 Chess 2 Rock Climbing >>> t = Topic.objects.get(id=1) # 根据id查看Chess模型的具体内容 >>> t.text 'Chess' >>> t.date_added datetime.datetime(2018, 4, 22, 2, 4, 3, 723045, tzinfo=<UTC>) >>> t.entry_set.all() # 查看该主题下的所有条目,通过外键查询,进行了人为换行 <QuerySet [<Entry: The opening is the first part of the game, roughly...>, <Entry: In the opening phase of the game, it's important t...>]>
创建网页:编写学习笔记
Django创建网页的过程通常分三个阶段:定义URL、编写视图和编写模板。
映射URL
打开learning_log
文件夹中的urls.py
,修改成如下内容:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('learning_logs.urls')) ]#此处有关namespace的在网上查询后好像搞到下面去了,不知道对不对
还需要在learning_logs
中创建另一个urls.py
文件:
'''定义learning_logs的url模式''' from django.urls import path from . import views app_name = 'learning_logs' urlpatterns = [ #主页 path(r'', views.index, name='index'),#原书中的正则不行 ]
总之,就是在learning_log/urls.py中添加learning_log中的所有URL,并匹配主页。
编写视图
打开learning_logs/views.py,添加
from django.shortcuts import render # Create your views here. def index(request): "学习笔记的主页" return render(request, 'learning_logs/index.html')
编写模板
在learning_logs
文件夹中新建一个templates
文件夹,再在这个文件夹中新建一个和APP同名的文件夹,即learning_logs
文件夹,最后,在这个learning_logs
文件夹中新建index.html
文件。index.html文件内容如下:
<p>Learning Log</p> <p>Learning Log helps you keep track of your learning, for any topic your're learning about.</p>
现在打开这个项目的基础URL------http://localhost/8000/,可以看到刚才创建的网页
创建其他网页
创建两个用于显示数据的网页,其中给一个列出所有的主题,另一个显示特定主题的所有条目。对于每个网页都指定URL模式,编写一个视图函数,并编写一个模板。但这么做之前,我们先创建一个父模板,项目中的其他模板都将继承它。
父模板base.html(在index.html所在的目录下)
<p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> <p> {% block content %}{% endblock content %}
第一段落是一个模板标签,它匹配到主页的链接。第二段插入了一对块标签,名为content,其中的内容将由子模板指定。
子模板index.html修改
{% extends "learning_logs/base.html"%} {% block content%} <p>Learning Log helps you keep track of your learning, for any topic your're learning about.</p> {% endblock content %}
第一段标签{% extends}表示继承哪个父模板,第二段,包含子模块的内容。
显示所有主题的页面
1.URL模式
修改learning_logs/urls.py
'''定义learning_logs的url模式''' from django.urls import path from . import views app_name = 'learning_logs' urlpatterns = [ #主页 path(r'', views.index, name='index'), #显示所有主题页面 path(r'topics', views.topics, name=topics)#定义并匹配URL注意Django2.0path不支持正则表达,如要使用需导入re_path,使用re_path ]#注意是中括号,不是大括号,这块出错花了我很长时间。。。
视图views.py
from django.shortcuts import render from .models import Topic # Create your views here. def index(request): "学习笔记的主页" return render(request, 'learning_logs/index.html') def topics(request): """显示所有的主题""" topics = Topic.objects.order_by('date_added')#访问数据库,将结果按时间排序并将查询集存储在 topics中 context = {'topics': topics}#上下文字典,发送给模板,键是用来访问数据的名称,值是发送给模板的数据 return render(request, 'learning_logs/topics.html', context)#这是一个渲染函数
模板
创建topics.html,并存储到index.html所在的目录下
{% extends "learning_logs/base.html"%} {% block content %} <p>Topics</p> <ul> {% for topic in topics%} <li>{{ topic }}</li> {% empty %} <li>No topics have been added yet.</li> {% endfor %} </ul> {% endblock content %}
修改父模板base.html,使其包含到显示所有主题的页面的链接
<p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> - <a href="{% url 'learning_logs:topics' %}">Topics</a> <p> {% block content %}{% endblock content %}
现在如果进入http://localhost:8000/,将看到添加的Topics链接,单击链接将看到
显示特定主题的页面
1.URL模式
修改learning_logs/urls.py
-----snip------ urlpatterns = [ -------snip------- #特定主题的详细页面 path(r'topics/<int:topic_id>/', views.topic, name='topic')#使用主题的ID来指出请求的是哪个主题 ]
视图views.py
函数topic()需要从数据库中获取指定的主题以及与之相关联的所有条目
------snip-------- def topic(request, topic_id): """显示单个主题及其所有条目""" topic = Topic.objects.get(id=topic_id) entries = topic.entry_set.order_by('-date_added')#减号指定降序排列 context = {'topic': topic, 'entries': entries} return render(request, 'learning_logs/topic.html', context)
模板
在index.html所在的目录下创建topic.html
{% extends "learning_logs/base.html"%} {% block content %} <p>Topic: {{ topic }}</p> <p>Entries:</p> <ul> {% for entry in entriies% } <li> <p>{{ entry.date_added|date:'M d, Y H:i' }}</p><p>{{ entry.text|linebreaks}}</p> </li> {% empty %} <li> There are no entries for this topic yet. </li> {% endfor %} </ul> {% endblock content %}
将显示所有主题页面中每个主题都设置为链接
修改topics.html
---------snip----- {% for topic in topics%} <li> <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a> </li> {% empty %} --------snip----------
刷新所有主题页面,点击Topics,选择某一主题,将看到类似于下图的画面。
小结
1.制定了简要的项目规范,在虚拟环境下安装了Django,创建项目并核实该项目已经正确的创建。
2.创建应用程序,定义表示应用程序数据的模型
3.创建数据库,修改模型后,Django可为迁移数据库提供怎样的帮助
4.创建超级用户
5.Django shell
6.定义URL,创建视图函数,编写模板(包括模板的继承)
本文为《Python编程:从入门到实践》笔记,并参考了博文https://segmentfault.com/a/1190000015098721