《Tango With Django2》Chapter6笔记 -- Models, Templates & Views

连接Models、Views和Template来提供动态内容。在本章中,将通过在主页上显示类别的过程,然后创建专门的类别页面来显示相关的链接列表。

1. Workflow:数据驱动页面

在Django中创建一个数据驱动的网页,五个主要步骤。
(1) 在views.py模块中,import希望使用的模型
(2) 在view函数中,查model以获得想要显示的数据
(3) 在view中,将model的结果传递到template的上下文中
(4) 创建/修改template,使其显示来自上下文的数据
(5) 如果还没有这样做,将URL映射到view

2. 在Rango主页显示category

(1) import需要的Models
打开rango/views.py,在文件的顶部其他import之后,从rango的models.py文件中导入Category模型

# Import the Category model 
from rango.models import Category

(2)&(3) 修改Index view

def index(request):
	# 查询数据库中当前存储的所有类别的列表
	# 按照喜欢的数量降序排列类别
	# 只检索前5个——如果小于5则检索全部。
	# 将列表放在context_dict字典中(带有粗体消息!) -- 它将被传递给模板引擎
	
	# 查询“类别”模型可检索前5个类别
	# order_by: 排序; 减号: 降序排列
	category_list = Category.objects.order_by('-likes')[:5] 

	context_dict = {}
	context_dict['boldmessage'] = 'Crunchy, creamy, cookie, candy, cupcake!'
	context_dict['categories'] = category_list
	# 渲染response并将其发送回去!
	return render(request, 'rango/index.html', context=context_dict)

(4) 修改Index Template
更新template/index.html

<!DOCTYPE html> 

{% load staticfiles %}

<html>

    <head> 
        <title>Rango</title> 
    </head>

    <body>

        <h1>Rango says...</h1> 
        <div>
            hey there partner! <br />
            <strong>{{ boldmessage }}</strong><br /> 
        </div> 

        <div> 
            {% if categories %}
                <ul>
                    {% for category in categories %} 
                    <li>{{ category.name }}</li>
                {% endfor %}
                </ul>
            {% else %}
                <strong>There are no categories present.</strong>     
            {% endif %}
        </div>    

        <div>
            <a href="/rango/about/">About Rango</a><br />
            <img src="{% static 'images/rango.jpg' %}" alt="Picture of Rango" />

        </div> 
    </body>

</html>			

(4) runserver
在这里插入图片描述

3. 创建详细信息页面

根据Rango的要求,我们还需要显示与每个类别相关联的页面列表
首先,必须创建一个新view。这个新视图必须被参数化。
我们还需要创建URL模式和URL字符串来编码类别名称
(1) 更新Category Table与一个slug字段
要创建可读的url,我们需要在Category模型中包含一个slug字段:
首先,从Django中导入函数slugify,它将用连字符替换空白,绕过百分比编码的问题
例如“how do i create a slug in django”变成了“how-do-i-create-a-slug-in django”

其次重写Category模型的save():
这个被重写的函数将调用slugify()函数并使用它更新新的slug字段。需要注意的是,每当category名发生变化时,slug也会发生变化——save()方法总是在创建或更新一个Django模型的实例时被调用。如下所示更新Category模型:

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()
    
    def save(self, *args, **kwargs):
        self.slug = slugify(self.name) 
        super(Category, self).save(*args, **kwargs)

    class Meta:
        verbose_name_plural = 'categories'

    def __str__(self):
        return self.name

(2) 迁移

$ python manage.py makemigrations rango

由于我们没有为该段代码提供默认值,并且我们在模型中已经有了现有的数据,因此makemigration命令将为您提供两个选项。选择提供默认值的选项(选项1),并输入一个空字符串——用两个引号表示(即’’)
在这里插入图片描述
然后迁移更改,并再次运行填充脚本以更新新的slug字段;重启server

$ python manage.py migrate 
$ python populate_rango.py
$ python manage.py runserver

(3)定制管理界面
输入Category名称时,它会自动预填充slug字段 ⇒ 用以下代码更新rango/admin.py

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

admin.site.register(Category, CategoryAdmin) #替换admin.site.register(Category)

(4) Categpry Page Workflow
为单个类别创建页面 --> 能够看到与一个类别相关联的页面。要实现类别页面,以便可以使用URL模式/rango/category/category-name-slug/访问它们,我们需要执行以下步骤:
a. 将Page模型导入rango/views.py中

from rango.models import Page

b. 在rango/views.py中创建一个名为show_category()的新view。show_category () 视图将接受第二个参数category_name_slug,它将存储编码后的类别名称。
•我们将需要辅助函数来编码和解码category_name_slug

def show_category(request, category_name_slug):
    # Create a context dictionary which we can pass 
    # to the template rendering engine. 
    context_dict = {}

    try:
        # Can we find a category name slug with the given name?
        # If we can't, the .get() method raises a DoesNotExist exception.
        # The .get() method returns one model instance or raises an exception. 
        category = Category.objects.get(slug=category_name_slug)

        # Retrieve all of the associated pages.
        # The filter() will return a list of page objects or an empty list. 
        pages = Page.objects.filter(category=category)

        # Adds our results list to the template context under name pages.
        context_dict['pages'] = pages

        # We also add the category object from # the database to the context dictionary.
        # We'll use this in the template to verify that the category exists.
        context_dict['category'] = category

    except Category.DoesNotExist:
        # We get here if we didn't find the specified category.
        # Don't do anything # the template will display the "no category" message for us.
        context_dict['category'] = None
        context_dict['pages'] = None

    # Go render the response and return it to the client.
    return render(request, 'rango/category.html', context=context_dict)

c. 创建一个新模板,templates/rango/category.html

<!DOCTYPE html>

<html>

    <head> 
        <title>Rango</title> 
    </head>

    <body>
        <div> 
        {% if category %} 
            <h1>{{ category.name }}</h1> 
            {% if pages %} 
            <ul> 
                {% for page in pages %}
                <li><a href="{{ page.url }}">{{ page.title }}</a></li>
                {% endfor %} 
            </ul> 
            {% else %} 
            <strong>No pages currently in category.</strong> 
            {% endif %} 
        {% else %} 
            The specified category does not exist.
            {% endif %} 
        </div> 
    </body>

</html>

d. 更新Rango的urlpatterns,将新的分类视图映射到 rango / urls. py
将category_name_url参数的值传递给show_category()函数
修改rango/urls.py文件并按如下方式更新urlpatterns元组

urlpatterns = [
    path('', views.index, name='index'),
    path('about/', views.about, name="about"),
    path('category/<slug:category_name_slug>/', views.show_category, name='show_category'),
    # 我们想要匹配一个字符串,它是一个slug,并将它赋值给变量category_name_slug
]

(5) 修改Index Template
我们的index页面模板需要更新,以便它链接到列出的类别页面
我们可以更新index.html模板,让它包含一个通过slug链接到category页面的链接

<ul>
	{% for category in categories %} 
    <li>
    	<a href="/rango/category/{{ category.slug }}/">{{ category.name }}</a>
    </li>
	{% endfor %}
</ul>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值