实战Django:Rango Part2

 

在这一节,我们将学习如何用自动脚本来添加内容,然后给我们的应用添加首页和一个内容页。

9.Part1练习答案


除了加入views和likes两个字段,这里我们需要思考一个问题,用户将如何来访问我们的页面?用/rango/category/1//rango/category/2/?他们怎么知道1代表哪个分类,2又代表哪个分类?有没有更直接一点的方法呢?

我想还是直接用分类名称来作为链接的一部分会比较好一些,比如用/rango/category/Python/来访问Python分类这样子。但碰到带空格的分类名称时,链接中的空格会被自动转义,因此,用一个别名来作为链接更为理想。

Django中有一个slugify的方法,它可以把帮助我们自动处理别名,比如我们的分类名是”how do i create a slug in django“,slugify会把它变成”how-do-i-create-a-slug-in-django“。

编辑rango/models.py文件,修改Category类:

rango/models.py:

from django.template.defaultfilters import slugify

class Category(models.Model):
    name = models.CharField(max_length=128, unique=True)
    views = models.IntegerField(default=0)
    likes = models.IntegerField(default=0)
    slug = models.SlugField(unique=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Category, self).save(*args, **kwargs)

    def __str__(self):
        return self.name

然后依次在dos命令提示符下运行如下命令:

$ python manage.py makemigrations rango
$ python manage.py migrate

注意:在model.py中对模型中的字段进行修改后,必须执行上述命令才能把数据库跟着改动。

加入slug字段后,我们希望在管理界面中输入分类名称时,自动生成slug字段,这个可以通过修改admin.py来实现。

编辑rango/admin.py 文件,让它变成下面这个样子:

rango/admin.py

from django.contrib import admin

from rango.models import Category, Page

class PageAdmin(admin.ModelAdmin):
    list_display = (‘title‘, ‘category‘, ‘url‘)

class CategoryAdmin(admin.ModelAdmin):
    prepopulated_fields = {‘slug‘:(‘name‘,)}

admin.site.register(Category, CategoryAdmin)
admin.site.register(Page, PageAdmin)

10.创建自动化脚本



这一次我们不再手动输入内容,而是采用自动化脚本的形式:用一个脚本来自动添加内容。

在项目根文件夹下创建populate_rango.py,加入如下内容:

rangoproject/populate_rango.py:

#!/usr/bin/env python
import os
import django

def populate():
    python_cat = add_cat(‘Python‘)

    add_page(cat=python_cat,
        title="Official Python Tutorial",
        url="http://docs.python.org/3/tutorial/")    add_page(cat=python_cat,
        title="How to Think like a Computer Scientist",
        url="http://www.greenteapress.com/thinkpython/")

    add_page(cat=python_cat,
        title="Learn Python in 10 Minutes",
        url="http://www.korokithakis.net/tutorials/python/")

    django_cat = add_cat("Django")

    add_page(cat=django_cat,
        title="Official Django Tutorial",
        url="https://docs.djangoproject.com/en/1.7/intro/tutorial01/")    add_page(cat=django_cat,
        title="Django Rocks",
        url="http://www.djangorocks.com/")

    add_page(cat=django_cat,
        title="How to Tango with Django",
        url="http://www.tangowithdjango.com/")

    frame_cat = add_cat("Other Frameworks")

    add_page(cat=frame_cat,
        title="Bottle",
        url="http://bottlepy.org/docs/dev/")

    add_page(cat=frame_cat,
        title="Flask",
        url="http://flask.pocoo.org")

    # 输出我们添加的内容.
    for c in Category.objects.all():
        for p in Page.objects.filter(category=c):
            print ("- {0} - {1}".format(str(c), str(p)))

def add_page(cat, title, url, views=0):
    p = Page.objects.get_or_create(category=cat, title=title, url=url, views=views)[0]
    return p

def add_cat(name):
    c = Category.objects.get_or_create(name=name, defaults=None)[0]
    return c

# 开始执行!
if __name__ == ‘__main__‘:
    print ("开始执行Rango自动化脚本...")
    os.environ.setdefault(‘DJANGO_SETTINGS_MODULE‘, ‘rangoproject.settings‘)
    django.setup()
    from rango.models import Category, Page
    populate()

我们来运行这个脚本,在dos命令提示符下输入命令:

python populate_rango.py

你会看到象这样的提示:

开始执行Rango自动化脚本...
- Python - Official Python Tutorial
- Python - How to Think like a Computer Scientist
- Python - Learn Python in 10 Minutes
- Django - Official Django Tutorial
- Django - Django Rocks
- Django - How to Tango with Django
- Other Frameworks - Bottle
- Other Frameworks - Flask

这个脚本自动往数据库里添加了三个分类,并在各个分类下添加了数量不等的页面数据。

我们来看一下这些数据添加后的效果。重新启动Django服务器,然后在浏览器地址栏里输入:

http://127.0.0.1:8000/admin/

按回车进入登录页面,输入账号和密码,登录成功后,点击链接“Pages”,可看到如下页面:

写这样一个脚本虽然要花上一点时间,但你若是在一个团队中做这个项目,你可以把这个脚本分发给团队中的其他人,那样,他们就可以很快创建好数据库。此外,这个脚本在测试中亦会派上用场。

11.在首页上显示分类



我们来回顾一下,要完成某页面显示,需要做哪些操作?

  • 编写视图
  • 创建模板
  • 设计URL

下面我们来一一完成。先编辑rango/views.py 文件,让它变成下面这样:

rango/views.py

from django.shortcuts import render
from rango.models import Category

def index(request):
    # 查询数据库中的所有分类;
    # 用likes字段排序;
    # 只显示前5个字段;
    # 把列表存入context_dict字典,再把这个字典传给模板引擎;
    category_list = Category.objects.order_by(‘-likes‘)[:5]
    context_dict = {‘categories‘: category_list}

    # 把context_dict字典传给模板引擎;
    return render(request, ‘rango/index.html‘, context_dict)

接下来我们来编辑首页模板,在templates文件夹(位于项目根文件夹下)中创建一个rango文件夹,然后在该文件夹下新建一个index.html文件,加入如下内容:

rangoproject/templates/rango/index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Rango</title>
    </head>

    <body>
        <h1>欢迎来到Rango!</h1>

        {% if categories %}
            <ul>
                {% for category in categories %}
                <li>{{ category.name }}</li>
                {% endfor %}
            </ul>
        {% else %}
            <strong>目前还没有可用分类。</strong>
        {% endif %}
    </body>
</html>

Tips:建议把所有的模板文件储存为UTF-8编码。

在{% if categories %} 这个语句中的categories ,就是我们视图里context_dict字典的数据,“if”是用来判断它是否存在。若存在,则用“for”语句把它逐条取出来——因为categories 是一个列表。

最后我们来设计URL,在rango文件夹下创建一个叫url.py的文件,然后添加如下内容:

rango/urls.py

from django.conf.urls import patterns, url
from rango import views

urlpatterns = patterns(‘‘,
        url(r‘^$‘, views.index, name=‘index‘))

编辑rangoproject/urls.py 文件,让它变成下面这样:

rangoproject/urls.py

from django.conf.urls import patterns, include, url
from django.contrib import admin

urlpatterns = patterns(‘‘,
    url(r‘^admin/‘, include(admin.site.urls)),
    url(r‘^rango/‘, include(‘rango.urls‘)),
)

好了,让我们在浏览器中访问一下http://127.0.0.1:8000/rango/,你会看到这样的页面:

12.创建内容页



现在,分类是显示出来了,我们还希望用户进入分类后,能看到每个分类里的内容。

先编写视图,编辑rango/views.py 文件,先在头部加入一行:

rango/views.py

from rango.models import Page

然后加入如下内容:

rango/views.py

def category(request, category_name_slug):

    # 定义要传递给模板引擎的context_dict字典。
    context_dict = {}

    try:
        # 是否能匹配到给定的分类别名?
        # 如果匹配不到,.get() 方法会提交一个DoesNotExist的异常;
        # 匹配到的话,我们就用它来在Page表中检索出该分类的数据;
        category = Category.objects.get(slug=category_name_slug)
       context_dict[‘category_name‘] = category.name

        # 获取该分类下的所有页面;
        pages = Page.objects.filter(category=category)

        # 把获取到的数据存入context_dict;
        context_dict[‘pages‘] = pages
        # 我们把分类名称也加入到context_dict中,这个值可用来在模板中校验分类是否存在。
        context_dict[‘category‘] = category
    except Category.DoesNotExist:
        # 如果找不到分类,那么啥都不做;
        # 模板会显示“没有分类”的信息;
        pass

    return render(request, ‘rango/category.html‘, context_dict)

现在我们来创建模板,在templates/rango文件夹下新建一个category.html文件,加入如入内容:

rangoproject/templates/rango/category.html

<!DOCTYPE html>
<html>
    <head>
        <title>Rango</title>
    </head>

    <body>
        <h1>{{ category_name }}</h1>
        {% if category %}
            {% if pages %}
            <ul>
                {% for page in pages %}
                <li><a href="{{ page.url }}">{{ page.title }}</a></li>
                {% endfor %}
            </ul>
            {% else %}
                <strong>当前分类下尚无可用页面.</strong>
            {% endif %}
        {% else %}
            指定的分类名称 {{ category_name }} 不存在!
        {% endif %}
    </body>
</html>

接下来我们重新设计URL,编辑rango/url.py的文件,把它变成下面这样:

rango/urls.py

from django.conf.urls import patterns, url
from rango import views

urlpatterns = patterns(‘‘,
    url(r‘^$‘, views.index, name=‘index‘),
    url(r‘^category/(?P<category_name_slug>[\w\-]+)/$‘, views.category, name=‘category‘),
)

除了这些,我们还需要修改一下首页的模板,让分类名称加上链接。编辑index.html,把它改成这样:

rangoproject/templates/rango/index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Rango</title>
    </head>

    <body>
        <h1>欢迎来到Rango!</h1>

        {% if categories %}
            <ul>
                {% for category in categories %}
                <!-- 下面这行给分类加入了超链接 -->
                <li><a href="/rango/category/{{ category.slug }}">{{ category.name }}</a></li>
                {% endfor %}
            </ul>
       {% else %}
            <strong>目前还没有可用分类。</strong>
       {% endif %}
    </body>
</html>

我们来检查一下工作成果

我们先访问首页,你会看到首页中列出了当前所有的分类,这些分类都是超链接。我们点击“Django”分类,这样,Django分类中的所有页面都显示出来了,点击“Official Django Tutorial”链接,它将会把我们带到Django官方实例的页面。

 

 

13.练习



1)创建一个”about”视图,关联的模板文件为about.html;

2)模板的标题叫“关于Rango”,可自由添加一些文字,但需要插入一个叫rango.jpg的图片(图片下载地址请看part1),图片存放在static文件夹下。

 

【未完待续】

本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!

作者:舍得

首发:舍得学苑@博客园

 
时间: 2024-08-06 00:15:27

实战Django:Rango Part2的相关文章

实战Django:小型CMS Part2

回顾一下我们之前讲过的几个实例的流程,现在,我们只要添加一些内容(用来测试),创建视图.模板和URL模式,就能完成这个小型的CMS了.   7.添加内容 我们先来创建一个分类,点击Categories后面的"增加"按钮,然后在Label文本框中输入:"Django",在slug文本框后面输入"django"(django不用输入也能自动出现,你可以改成自己喜欢的名字): 随后点击后面的"保存"按钮. 点击左上方的"首

实战Django:Rango Part1

在前面我们已经陆续学习了六个Django的实例,其中一个来自Django官方的文档,另外五个来自<Django Web开发指南>.舍得介绍的每一个实例,都是按照官方文档的标准,力求让大家在根据文章去做自己的实例时,能够按"文"索骥,轻松再现整个实例的制作过程. 接下来,舍得要介绍一个大型的实例,这个项目叫做Rango,它来自Django圈内口碑甚佳的<How to Tango with Django>一书.事实上,此书就是围绕Rango这一个实例来展开的,而且,

实战Django:Rango Part6

24.优化模板 在这个项目中,从已经做过的模板来看,你可能会注意到里面有很多重复的代码.这种重复不仅带来大量无谓的工作量,而且以后调整起来也极为不便. 因此,最理想的做法是将那些重复的代码放到基础模板中,然后从基础模板再扩展出一个个新的模板. 我们先来做这个基础模板,在templates/rango文件夹下新建一个base.html文件,然后添加以下内容: templates/rango/base.html: <!DOCTYPE html> <html> <head>

实战Django:Rango Part7

26.用Django-Registration-Redux进行用户校验 Django中,有好多现成的应用提供了注册.登录.校验等功能,我们只要稍稍改动一下URL映射.视图和模板就可以使用它们.在这一章,我们将介绍用Django-Registration-Redux,顺便学习一下如何把外部的应用加到我们的项目中. (1)安装Django-Registration-Redux 在Dos命令提示符下转到Python的Scripts文件夹,然后运行如下命令: pip install django-reg

实战Django:简易博客Part2

在Part1中,我们完成了本项目的基本框架搭建,并完善了一下管理后台,现在我们来看如何设计面向公共的页面部分. 8.创建模板 首先,请在blog文件夹下建立templates文件夹,然后,在templates文件夹中建立一个叫bog的文件夹,在这个bog文件夹下新建一个archive.html文件,这个文件的路径应该是: bog/templates/bog/archive.html 把下面这些代码添加到archive.html中: bog/templates/bog/archive.html:

实战Django:简易博客Part1

舍得学习新技能的时候,通常不喜欢傻读书--捧着一本阐述该项技能的书籍,然后傻看,一路看下来,脑子里塞满了新的概念.知识点,头是越来越大,但技能却几乎没掌握半分. 多年来,舍得养成了用做实例来学习新技能的习惯.这可不是舍得的独创,在象棋.围棋界中,历来有"打谱"一说,就是根据棋谱,把一步步棋摆出来,在打谱的过程中,去感悟.去吸收,此时感悟到的.吸收进的,才是属于你自己的东西.新的技能就这样一步步发展起来,逐渐壮大. 就象Django官方文档那样,一个实例看起来很简单,但作为初学者,用&q

实战Django:官方实例Part1

[写在前面] 撰写这个实战系列的Django文章,是很久之前就有的想法,问题是手头实例太少,一旦开讲,恐有"无米下锅"之忧. 随着对Django学习的深入,渐渐有了些心得,把这些心得整理出来,以规范的.方便新人上手的撰写方式来写这个实战系列,相信对刚接触Django的童鞋会有一定的帮助. 舍得这里所用到的版本,为Django 1.7.1,Python 3.2,想要按照舍得讲解的实例上手练习的话,请务必与舍得所用的版本保持一致. 实例是在Windows系统下调试的,如果你采用的是非Win

实战Django:Pastebin

  这是<Django Web开发指南>中的最后一个实例.如果说上一个实例Liveblog重点讲的是Django和Ajax的协作,那么我们在Pastebin中,将学习到Django和高亮语法JS的协作,顺便复习一下在Django中加入表单. 1.创建项目和应用 我们先来创建本实例的项目,在dos命令提示符下转到Scripts文件夹(如"c:\python32\Scripts"),然后运行如下命令: $ django-admin startproject pastebinpr

实战Django:小型CMS Part1

CMS,即Content Management System,内容管理系统.我们这里要开发的小型CMS应用,从结构上和blog应用有些类似,但我们会在这里加入一些新的技术,比如说工作流.搜索功能.编辑组件等. 1.创建项目和应用 我们先来创建本实例的项目,在dos命令提示符下转到Scripts文件夹(如"c:\python32\Scripts"),然后运行如下命令: $ django-admin startproject cmsproject 然后在dos命令提示符下继续输入如下命令,

实战Django:LiveBlog

<Django Web开发指南>的实例讲的差不多了,除了今天要介绍的LiveBlog,还有一个Pastebin.这样,书中的实例基本讲完了.做完这些实例之后,舍得建议回头看看这本书,或许你会从书中找到舍得所讲的实例里忽略掉的一些细节.此外,<Django Web开发指南>中有几个章节是关于Django的基础或高级技术的,建议阅读并设法把它应用到你所练习过的实例中. 正如你已经看到的,Django提供了丰富的内置功能,你可以很轻松地用这些功能来完成很多工作.但和所有的工具一样,Dja