第六十九天 BBS项目之五 js与模板语法 inclusion_tag实操,文章详情,点赞点踩

tuq2791 / 2024-03-11 / 原文

一、昨日内容回顾

# 1 首页文章的渲染
	-模板语法的for循环
    -bootstrap的媒体组
    -显示头像: articel.blog.userinfo  有可能没有 :在admin中建立关系
    	-注册---》申请开启博客功能
    -图标库
    	-font-awesome-4.7.0
        
# 2 个人站点样式
	-头部导航栏
    -左侧筛选:3个面板
    -右侧文章列表:首页文章列表差不多
    
    -使用了模板继承---》base.html----》尽量多的写block
# 3 个人站点左侧 标签,分类,随笔档案的渲染
	-查询出标签id,名字,标签下的文章数
    -查询出分类id,名字,分类下的文章数
    -查询出时间名字,时间下的文章数
    
    -查分类id,名字,当前博客下的----》单表查询+过滤
    -查分类id,名字,当前博客下的,分类下的文章数---》分组  group by
    selcet category.id,category.name,count(article.id) as c from category,article where category.id=article.cagegory and category.blog=2 group by category.id; Category.object.filter(blog=user.blog).values('id').annotate(c=Count(articel__id)).values('id','name','c')

    
# 4 左侧点击过滤
	-设计路由
    	-按标签过滤:/lqz/tag/标签id号.html
        -按分类过滤:/lqz/category/分类id号.html
        -按时间过滤:/lqz/archive/202209.html
    -三个路由归一
    	re_path('^(?P<name>\w+)/(?P<type_name>tag|category|archive)/(?P<condition>\d+).html', views.site),

    -视图函数,统一用site视图函数
    	-

### 扩展作业
# 原来轮播图使用模板语法渲染的
# 轮播图使用ajax渲染
-当页面加载完成发送ajax请求

    $(function () {
       $.ajax({
           url:'/get_banner/',
           type:'get',
           success:function (data){
               console.log(data)
               // {code:100,msg:成功,data:[{id:1,img:/banner/bannner1.jpg,name:'asdf',link:'/login/'},{id:1,img:/banner/bannner1.jpg,name:'asdf',link:'/login/'}]}
               // 通过dom操作,把img地址,放到 轮播图img的src中即可
           }
       })
    })

def get_banner(request):
    res = Banner.objects.all().values('id', 'img', 'name')[:2]
    # 如果这里用JsonResponse序列化不了,把res转成列表套字典的形式
    return JsonResponse({'code': 100, 'msg': '成功', 'data': res})
"""
$(function ()就是文件加载完成的意思
windows.onload也行
"""

二、模板和模板语法的区别

# 模板语言---》模板---》不是前端页面---》区分开
-django中:模板语法,dtl:django template language,django自己设计,写的
-flask中:模板语法:jinja2,第三方
-java: jsp  理解为:java web 的模板语言
-php:  php  <? php语言 >

-xx.html 中写了python代码,这个不是前端页面,叫模板
"""
个人的理解是前端就是用前端自己的语言写的。模板的渲染是后端完成的,所以前端中的python语言理论上为模板
"""

views.py中
def test(request):
    return render(request, 'test.html',
                  context={'name': "lqz", 'age': 19, 'a': 'a', 'l': [1, 2, 3], 'd': {'name': 'lyf', 'age': 40}})
——————————————————————————————————————————————————
test.html中
<script>
    // 可以在js代码用模板渲染,但是只能用数字,字符串(加引号),列表  不能用元组,字典,对象   test
    // 后端模板中得name给js的name
    var name ='{{name}}'
    // 后端模板中得age给js的age
    var age = {{ age }}
    var l= {{ test }}
    //var d={'name': 'lyf', 'age': 40}

    console.log(age)
    console.log(name)
    console.log(l)
    //console.log(d)

    $('h2').html(age)

    // 把js的变量l,给python的视图函数中得l

</script>
"""
1.对于结果是数字的,就没有问题
2.对于结果是字符串的
var name ={{name}} 本质上是
var name = lqz   所以会报错
var name ='{{name}}'   就得自己加上引号
3.不能用元组,字典,对象   test
"""

三、左侧使用inclusion_tag方案实现(第58天也有)

首先是inclusion_tag的作用,是可以让一部分的网页作为可以用模型渲染的函数调用
# 自定义标签
-第一步:在app中创建包:templatetags
-第二步:在包下新建py文件:如:my_tags.py
-第三步:在py文件中导入
from django import template
第四步:实例化得到对象
register = template.Library()
第五步:使用register装饰函数
@register.inclusion_tag('left.html', name='left')
def left(name):
	return {}  # 字典的数据可以在left.html中使用
 -第六步:在想引入inclusion_tag使用---》base.html 的栅格左侧占2个栅格的位置
{% load my_tags %}
{% left  name%}
may_tag文件中

from django import template
from blog import models
from django.db.models.functions import TruncMonth, TruncDay, TruncYear, TruncHour
from django.db.models import Avg, Max, Min, Count

register = template.Library()


@register.inclusion_tag('left.html', name='left')
def left(name):
    user = models.UserInfo.objects.filter(username=name).first()
    tag_res = models.Tag.objects.filter(blog=user.blog).values('id').annotate(c=Count('article__id')).values_list('id', 'name', 'c')
    category_res = models.Category.objects.filter(blog=user.blog).values('id').annotate(c=Count('article__id')).values_list('id', 'name', 'c')
    data_res = models.Article.objects.filter(blog=user.blog).annotate(year_month=TruncMonth('create_time')).values('year_month').annotate(c=Count('id')).values_list('year_month', 'c')
    print(tag_res)
    print(category_res)
    print(data_res)
    return {'tag_res': tag_res, 'category_res': category_res, 'data_res': data_res,'user': user}  # 返回的字典,可以在left.html中使用
left 文件中(部分)

<div class="panel panel-success">
    <div class="panel-heading">
        <h3 class="panel-title">我的标签</h3>
    </div>
    <div class="panel-body">
        <div>
            {% for tag in tag_res %}
                <div>
                    <a href="/{{ user.username }}/tag/{{ tag.0 }}.html">
                        <sapn>{{ tag.1 }}</sapn>
                        <span>{{ tag.2 }}</span>
                    </a>
                </div>
            {% endfor %}
        </div>
    </div>
</div>
具体使用在了base.html中
<div class="container-fluid">
    <div class="row">
        <div class="col-md-2">
            {% load my_tag %}
            {% left name %}
        </div>
        <div class="col-md-10">
            {% block article %}

            {% endblock %}
        </div>
    </div>
</div>

"""
总结:
1.templatetags文件名千万别写错
2.'left.html'表示拿来作为模块的文件,name='left'可以不写,默认就是下面的函数名
@register.inclusion_tag('left.html', name='left')
def left(name):
	return {}  # 字典的数据可以在left.html中使用
3缺啥参数就传啥参数,name比较特殊因为在渲染base的时候name就已经被site获取到了,就可以利用
{% left name %}传输给left
"""