Pythone入门到实践-学习笔记-Day9
第十八章 Django入门
一、建立项目
项目规范:项目规范详细说明了项目的目标,阐述了项目的功能,并讨论了项目的外观和用户界面
要使用Django,首先要建立一个虚拟工作环境。虚拟环境是系统的一个位置,你可以 其中安装包,并将其与其他Python包隔离,将项目的库与其他项目分离是有益的,且为了部署到服务器,这也是必须的。
先为项目建立一个目录,并在这个目录下创建一个虚拟环境
d:\python\Django>python-m venv ll_env
激活虚拟环境
ll_env\scripts\activate.bat
停止使用虚拟环境
ll_env\scripts\deactivate.bat
安装Django
pip install Django
在Django中创建目录
django-admin.py startproject learning_log .
末尾的句点让新项目使用合适的目录结构,千万别忘记这个句点,否则部署应用程序时将遇一些配置问题。
创建数据库
python manage.py migrate
首次执行命令migrate时,将让Django确保数据库与项目的当前状态匹配,创建必要的数据库表,用于存储我们将在这个项目中的信息,再确保数据库结构与当前代码匹配,此时生成
db.sqlite3
数据库文件,SQLite是一种使用单个文件的数据库,是编写简单应用程序的理想选择。
查看项目
python manage.py runserver
浏览器显示结果Django启动一个服务器,能查看系统中的项目,了解它们的工作情况。当在浏览器输入URL:http://127.0.0.1:8000/请求网页时,Django服务器将进行响应,生成网页,并发送给浏览器。
ctrl + c
关闭服务器
二、创建应用程序
Django项目由一系列应用程序组成,它们协同工作,让项目成为一个整体。
创建应用
python manage.py startapp learning_logs
startapp <appname>
命令让Django建立创建应用程序的基础设施(models.py,admin.py和views.py)
定义模型
打开models.py,新增Topic
类
from django.db import models
class Topic(models.Model):
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.text
CharField
是由字符或文本组成的数据,max_lenght=200
最多存储200个字符;
DateTimeField
是记录日期和时间的数据,auot_now_add=True
,当新增时,Django将这个字段设置成当前日期和时间;
__str__()
返回存储在属性text中的字符串
激活模型
要使用模型,必须让Django将应用程序包含到项目中
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'learning_logs',
]
在
settings.py
文件中,将应用程序learing_logs
添加到INSTALLED_APPS
元组,接下来,让Django修改数据库python manage.py makemigrations learning_logs
,命令makemigrations
让Django该如何修改数据库
python manage.py makemigrations learning_logs
输出:Migrations for 'learning_logs':
0001_initial.py: - Create model Topi,并创建一个名为0001_initial.py的迁移文件,这个文件将在数据库中为模型Topic创建一个表。
应用迁移,Django修改数据库:
python manage.py migrate
输出:
Running migrations:
Rendering model states... DONE
Applying learning_logs.0001_initial... OK
每当需要修改管理的数据时,都采取如下三个步骤:1、修改models.py
;
2、对learning_logs调用makemigrations
(python manage.py makemigrations learning_logs);
3、让Django迁移项目python manage.py migrate
管理网站
1、创建超级用户
python manage.py createsuperuser
#提示输入超级用户名,eMail,两次密码
2、向管理网站注册模型
打开admin.py
,向管理网站注册Topic
from learning_logs.models import Topic
admin.site.register(Topic)
浏览器运行结果admin.site.register()让Django通过管理网站管理模型
3、定义模型Entry
class Topic(models.Model):
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.text
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[:20]+ "..."
models.ForeignKey(Topic):关联Topic外键
on_delete=models.CASCADE:当主表删除时从表中的数据也一起删除
4、Django shell
python manage.py shell
>>>from learning_logs import Topic
>>>Topic.objects.all()
#输出:
<QuerySet [<Topic: Study Django>, <Topic: Study python>]>
>>>topics = Topic.objects.all()
>>>for topic in topics:
print(ttopic.id,topic)
>>>t = Topic.objects.get(id=1)
>>>t.text
#通过外键获取Entry数据
>>>t.entry_set.all()
每次修改模型后,都需要重启shell,这样才能看到修改后的效果,退出shell,Linux:Ctrl + D,Windows:Ctrl + Z,再按回车。
三、创建网页
使用Django创建网页分三个阶段:定义URL;编写视图和编写模板。URL定义让Django知道如何将浏览器请求与网站URL匹配,以确定返回哪个网页。
1、映射URL
打开项目文件夹learning_log中的文件urls.py.
"""learning_log URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
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'))
"""
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
#添加learning_logs的URL和APP_NAME,实参namespace将同项目中的其它URL区分开来 path(r'',include(('learning_logs.urls','learning_logs'),namespace='learning_logs')),#
]
在learing_logs目录下创建urls.py
#导入url
from django.conf.urls import url
#导入views
from . import views
urlpatterns = [
#主页
url(r'^$',views.index,name='index')
#显示所有主题
url(r'^topics/$',views.topics,name='topics')
#显示特定主题的详细页面
url(r'^topics/(?P<topic_id>\d+)/$',views.topic,name='topic')
]
url()参数:第一参数正则表达式匹配请求URL,正则表达式通常被为regex,几乎每种语言都使用它
第二参数指定要调用的视图函数
第三个参数将这个URL模式的名称指定为index,可以其它地方引用它,当需要提供这个链接时,直接使用这个名称,而不用编写URL
2、编写视图
视图函数接受请求中的信息,准备好生成网页所需的数据,再将这些数据发送给浏览器
learning_logs中的文件views.py在执行
python manage.py startapp
时自动生成的。
#导入render()函数,根据视图提供的数据渲染响应
from django.shortcuts import render
def index(request):
return render(request,'learning_logs/index.html')
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)
URL请求与定义的模式匹配时,Django将在文件views.py中查找函数index(),再将请求对象传递给视图函数
3、编写模板
模板定义网页的结构,指定网页是什么样的,每当网页请求时,Django填入相关数据,模板能访问视图提供的任何数据。
在文件夹learning_logs下建立templates目录,在再templates目录下建立learning_logs目录,然后在learning_logs下建立index.html
<p>Learing_Log</p>
<p>Learning Log helps you keep track of your learning,for any topic you're learning about.</p>
4、模板继承
创建网站时,很多页面都有可能包含相同的元素,所以,编写一个包含通用元素的父模板,并让每个网页都继承这个模板,不必在每个页面中重复定义这些通用元素。
#父模板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 %}
#子模板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%}
#子模板topics.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:{{ 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>No entry for this topic yet </li>
{% endfor %}
</ul>
{% endblock content%}
主页在Django模板中,竖线(|)表示模板过滤器--对模板变量的值进行修改的函数,过滤器
M d,Y H:i
以这样的格式显示时间戳;过滤器linebreaks
将包含换行符的长条目转换为浏览器能够理解的格式。
主题页
详情页