Python Web应用程序(一)Django入门

系统: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

 

posted @ 2019-04-23 19:31  椰汁软糖  阅读(1228)  评论(0编辑  收藏  举报