zoukankan      html  css  js  c++  java
  • 实战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”,可看到如下页面:

    1

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

    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/,你会看到这样的页面:

    2

    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文件夹下。

    【未完待续】

    本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
    作者:舍得
    首发:舍得学苑@博客园

     
  • 相关阅读:
    Setting up a Reverse Proxy using IIS, URL Rewrite and ARR
    Compare xml files using C# LINQ
    ABAP术语-Authorization Object
    ABAP术语-Authorization Check
    ABAP术语-Authorization
    ABAP术语-Application Server
    ABAP术语-Application
    ABAP术语-APO (Advanced Planner and Optimizer)
    ABAP术语-ALE
    ABAP术语-Accounting Document
  • 原文地址:https://www.cnblogs.com/emagic/p/4168475.html
Copyright © 2011-2022 走看看