文章目录
前言
Windows下利用Django框架进行Web应用开发
Python三剑客第一本踩坑,学习笔记接上一节
一、创建应用程序
Django项目由一系列应用程序组成,它们协同工作让项目成为一个整体,先创建一个程序
(p_env) ...\practice>python manage.py startapp learning_logs
创建learning_logs应用程序,新增learning_logs文件夹
打开practice_p下的settings.py文件,在项目中添加该程序
我们创建了一个学习笔记应用程序并将其包含在项目中,接下来我们可以考虑笔记中所涉及的数据有哪些。
二、定义数据模型
学习笔记中至少需要两种数据,一个是主题,一个是条目,打开文件中models.py
添加主题数据模型Topic,代码如下:
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模型添加完后如下:
接下来让Django迁移并修改数据库,运行完后可以看到生成0001__init__.py文件
每当需要修改学习笔记管理的数据时,都采取以下三个步骤:修改models.py;对learning_logs调用makemigrations;让Django迁移项目
三、管理网站
1.创建管理员
(p_env) ...\practice>python manage.py createsuperuser
邮箱地址可以不填,密码输入不外显,直接输入两遍就可(不输入密码无法登录,不可以空密码)
2.向管理网站注册模型
打开learning_logs\admin.py文件,注册我们的模型
输入下面代码:
from learning_logs.models import Topic
admin.site.register(Topic)
保存,接下来进入网站 http://127.0.0.1:8001/admin/,使用刚刚创建的管理员账号登录
进入网站之前务必runserver打开网络服务,接上一节内容,不然会显示无法访问
进入页面就可以看到我们刚注册的模型了
接下来我们创建一个Chess主题,单击Topics的Add,输入主题,save,创建成功
3.新增模型Entry作为每个主题的内容条目
打开models.py文件,输入以下代码:
class Entry(models.Model):
"""学到的有关某个主题的具体知识"""
topic = models.ForeignKey(Topic, on_delete = models.CASCADE)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add = True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
"""返回模型字符串表示"""
return self.text[:50] + "..."
第一个属性topic是一个ForeignKey实例,通过外键将Entry关联到每个Topic。Meta类定义了复数表示为Entries,可以试试不定义Meta类,那么网页中将显示Entrys来表示条目,最后方法__str__()使我们显示条目中前五十个字符并添加省略号来代替显示所有文本。
定义完新模型之后不要忘记保存并迁移数据库(见步骤二):
接下来还需在admin.py中注册Entry模型,修改如下:
返回网页刷新我们可以看到新增了Entries条目
接下来我们新增一个Rock Climbing主题,并给两个主题增加条目,内容如下:
1.
The opening is the first part of the game, roughly the first ten moves or so. In the opening, it’s a good idea to do three things — bring out your bishops and knights, try to control the center of the board, and castle your king.(国际象棋的第一个阶段是开局,大致是前10步左右。在开局阶段,最好做三件事情:将马和象调出来;努力控制棋盘的中间区域;用车将王护住。)
Of course, these are just guidelines. It will be important to learn when to follow these guidelines and when to disregard these suggestions.(当然,这些只是指导原则。学习什么情况下遵守这些原则、什么情况下不用遵守很重要。)
2.
In the opening phase of the game, it’s important to bring out your bishops and knights. These pieces are powerful and maneuverable enough to play a significant role in the beginning moves of a game.(在国际象棋的开局阶段,将象和马调出来很重要。这些棋子威力大,机动性强,在开局阶段扮演者重要角色。)
3.
One of the most important concepts in climbing is to keep your weight on your feet as much as possible. There’s a myth that climbers can hang all day on their arms. In reality, good climbers have practiced specific ways of keeping their weight over their feet whenever possible.(最重要的攀岩概念之一是尽可能让双脚承受体重。有谬误认为攀岩者能依靠手臂的力量坚持一整天。实际上,优秀的攀岩者都经过专门训练,能够尽可能让双脚承受体重。)
Django Shell
我们能够使用交互式环境来显示系统内部的数据,也能够用于系统的测试,以下为示例
注意四个点:
1.如果显示Ipython已存在或者关于Ipython的问题,转上一节虚拟环境设置
2.for循环下print需要缩进两格
3.通过外键关系获取数据可以使用相关模型小写名称+下划线+set来获取,例如t.entry_set
4.退出使用Ctrl+Z,每次修改模型需重新启动shell
四、创建网页
使用Django创建网页通常分三个阶段:定义URL,编写视图和编写模板。
1.映射URL
打开urls.py文件
添加learning_logs的URL,书上代码有些过时,可用代码如下:
path('', include(('learning_logs.urls','learning_logs'), namespace = 'learning_logs')),
在learning_logs中创建另一个urls.py文件,加入代码:
"""定义learning_logs的URL模式"""
from django.urls import path, include
from . import views
urlpatterns = [
# 主页
path('', views.index, name = 'index'),
]
2.编写视图
打开learning_logs下的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')
3.编写模板
在learning_logs中新建templates文件夹,在该文件夹中新建learning_logs文件夹,再该路径下新建index.html文件,添加代码
<p>Learning Log</p>
<p>
Learning Log helps you keep track of your learning, for any topic you're learning about.
</p>
现在我们再回到我们的网站上就能够看到主页显示了。
报错SyntaxError: (unicode error) ‘utf-8’ codec can’t decode byte 0xb6 in position 0: invalid start byte,则把""“定义learning_logs的URL模式”""这一行删除或者注释掉,如果想保留可以百度找到VS高级保存选项设置UTF-8编码即可
五、创建其他网页与链接
接下来书中内容不多赘述,创建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 %}
创建topic.html页面,添加代码:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li>
<a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}
创建topic.html页面,添加代码:
{% extends 'learning_logs/base.html' %}
{% block content %}
<p>Topic</p>
<p>Entries:</p>
<ul>
{% for entry in entries %}
<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 %}
修改index.html代码如下:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>
Learning Log helps you keep track of your learning, for any topic you're learning about.
</p>
{% endblock content %}
加入链接
打开views.py,增加代码
def topics(request):
"""显示所有的主题"""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
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)
打开urls.py,加入显示页面链接:
# 显示所有主题
path('topics', views.topics, name = 'topics'),
# 特定主题的详细页面
path('topics/(?P<topic_id>\d+)', views.topic, name = 'topic'),
如若报错将?P中的P改成小写即可。
进入网站
进入网站之后我们就可以单击选项来查看相应的笔记内容了
总结
可以看到最后一步的时候还是出了些小bug,显示的并不是topic/1/,这个问题经过试验可以直接使用<topic_id>来表示目录下第几条条目,而不用(?p<topic_id>\d+),应该是Django版本更新之后简化了表示方法
条目路径修改如下:
path('topics/<topic_id>/', views.topic, name = 'topic'),
再次打开网页
如图所示成功显示/topic/2/,本节结束。