BBS02--动态展示用户名、admin管理、头像展示、图片防盗链、个人站点页、文章按日期分类、侧边栏筛选

1 首页-动态展示用户名

# 1.动态展示用户名称
    {% if request.user.is_authenticated %}
        <li><a href="#">{{ request.user.username }}</a></li>
        <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">更多操作 <span class="caret"></span></a>
            <ul class="dropdown-menu">
                <li><a href="#">修改密码</a></li>
                <li><a href="#">修改头像</a></li>
                <li><a href="#">后台管理</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">退出登陆</a></li>
            </ul>
    	</li>
    {% else %}
        <li><a href="{% url 'reg' %}">注册</a></li>
        <li><a href="{% url 'login' %}">登陆</a></li>
    {% endif %}
          
# 更多操作

2 admin后台管理

##### settings.py  
# 设置语言及时区:中文
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False

# admin后台管理
django提供了一个可视化的界面 用来方便对模型表
进行数据的增删改查操作

# 注册模型表  应用下admin.py中注册模型表
from django.contrib import admin
from app01 import models
# Register your models here.

admin.site.register(models.UserInfo)
admin.site.register(models.Blog)
admin.site.register(models.Category)
admin.site.register(models.Tag)
admin.site.register(models.Article)
admin.site.register(models.Article2Tag)
admin.site.register(models.UpAndDown)
admin.site.register(models.Comment)


# admin会给每一个注册了的模型表自动生成增删改查四条url
http://127.0.0.1:8000/admin/app01/userinfo/  查
http://127.0.0.1:8000/admin/app01/userinfo/add/  增
http://127.0.0.1:8000/admin/app01/userinfo/1/change/  改
http://127.0.0.1:8000/admin/app01/userinfo/1/delete/  删   
# 关键点就在于urls.py中的第一条自带的url



# 1.数据绑定尤其需要注意的是用户和个人站点不要忘记绑定了

# 2.标签

# 3.标签和文章
    千万不要把别人的文章绑定标签

3 用户头像展示

# 1 网址所使用的静态文件默认放在static文件夹下
# 2 用户上传的静态文件也应该单独放在某个文件夹下


# media配置
  该配置可以让用户上传的所有文件都固定存放在某一个指定的文件夹下
  # 配置用户上传的文件存储位置   会自动创建多级目录
  MEDIA_ROOT = os.path.join(BASE_DIR,'media')  # 文件名 随你 自己
  
  # 配置media的令牌路径  (与开放资源访问路径无关,只是模板语法的令牌)
  MEDIA_URL = '/media/'  # html 就是可以使用模板语法

  eg:  {{MEDIA_URL}}  = '127.0.0.1/media/'
     <a href="{{ MEDIA_URL }}avatars/222.jpg">查看media目录下的一张图片</a>


# 如何开设后端指定文件夹资源
首先你需要自己去urls.py书写固定的代码
from django.views.static import serve
from BBS14 import settings

# 开放资源访问路径url
url(r'^media/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT})

4 图片防盗链

# 如何避免别的网站直接通过本网站的url访问本网站资源

# 简单的防盗
  我可以做到请求来的时候先看看当前请求是从哪个网站过来的
  如果是本网站那么正常访问
  如果是其他网站直接拒绝
  请求头里面有一个专门记录请求来自于哪个网址的参数
    Referer: http://127.0.0.1:8000/xxx/

# 如何避免
# Referer字段实际上告诉了服务器,用户在访问当前资源之前的url位置。这往往可以用来用户跟踪

1.修改请求头header 不发送请求头referer 
  1.1 浏览器不会发送Referer字段
      rel="noreferrer"
        
  1.2 不发送Referer字段。(常用)
      referrerpolicy="no-referrer"
            
2.直接写爬虫把对方网址的所有资源直接下载到我们自己的服务器上

5 个人站点页

# 由于url方法第一个参数是正则表达式
  所以当路由特别多的时候,可能会出现被顶替的情况,针对这种情况有两种解决方式
    
  1.修改正则表达式
  2.调整url方法的位置


# 1.页面布局不再是282 变成左右布局
# 2.个人站点每个人的样式都不一样内部大致如何实现的
    内部给每个人开设了可以自定义css和js的文件接口
    并且用户自定义之后会将用户的文件保存下来,
    之后在打开用户界面的时候会自动加载用户自己写的css和js
    从而实现每个用户界面不一样的情况
	
# 3.侧边栏展示问题  制作成inclusion_tag:left_menu
    只要你的orm学的没有问题一般情况下不会有难度
    只要是queryset对象就可以无限制的点击queryset对象方法
        filter().filter().filter().filter()
	
    # 1 查询当前用户所有的分类及分类下的文章数
    category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count(
        'article__pk')).values_list('name','count_num','pk')
    # print(category_list)  # <QuerySet [('jason的分类一', 2), ('jason的分类二', 1), ('jason的分类三', 1)]>

    # 2 查询当前用户所有的标签及标签下的文章数
    tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list(
        'name','count_num','pk')
    # print(tag_list)  # <QuerySet [('tank的标签一', 1), ('tank的标签二', 1), ('tank的标签三', 2)]>

    # 3 按照年月统计所有的文章
    date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values(
        'month').annotate(count_num=Count('pk')).values_list('month','count_num')
    # print(date_list)
		
# 4.侧边栏筛选功能
    1.多个url公用一个视图函数
    2.当多个url公用一个视图函数的时候 你应该思考着多个url能不能优化一下
    # 个人站点页面搭建
    url(r'^(?P<username>\w+)/$',views.site,name='site'),
    
    # 侧边栏筛选功能
    # url(r'^(?P<username>\w+)/category/(\d+)/',views.site),
    # url(r'^(?P<username>\w+)/tag/(\d+)/',views.site),
    # url(r'^(?P<username>\w+)/archive/(\w+)/',views.site),
    # 上面的三条url其实可以合并成一条
    url(r'^(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)/',views.site)
	
    #### view.py 根据匹配参数 判断
	if kwargs:
        # print(kwargs)  # {'condition': 'tag', 'param': '1'}
        condition = kwargs.get('condition')
        param = kwargs.get('param')
        # 判断用户到底想按照哪个条件筛选数据
        if condition == 'category':
            article_list = article_list.filter(category_id=param)
        elif condition == 'tag':
            article_list = article_list.filter(tags__id=param)
        else:
            year,month = param.split('-')  # 2020-11  [2020,11]
            article_list = article_list.filter(create_time__year=year,create_time__month=month)

# 5.手动补全侧边栏url即可

6 按日期分类-文章数量

# 全是每个用户都可以有自己的站点样式
<link rel="stylesheet" href="/media/css/{{ blog.site_theme }}/">

# 实现:按照月进行分类
  id	content 	create_time		month
  1	111		2020-11-11		2020-11
  2	222		2020-11-12		2020-11
  3	333		2020-11-13		2020-11
  4	444		2020-11-14		2020-11
  5	555		2020-11-15		2020-11


# django官方提供一个orm语法
    from django.db.models.functions import TruncMonth
    
    Sales.objects
    .annotate(month=TruncMonth('timestamp'))  # 按照月份分组(指定时间字段)
    .values('month')  # 拿到按月份分组后的数据
    .annotate(c=Count('id'))  # 根据id或者pk字段统计(主键字段)
    .values('month', 'c')  #  拿到月份分组,和统计数量
			
			
# 时区问题报错
# 后端和django模板前端 采用 中国时区显示
TIME_ZONE = 'Asia/Shanghai'

# 是否让数据库统一采取 0时区进去存储
USE_TZ = True

7 侧边栏筛选功能

https://www.cnblogs.com/jason/tag/Python/  		标签
https://www.cnblogs.com/jason/category/850028.html 	分类
https://www.cnblogs.com/jason/archive/2016/10.html 	日期
  
  
https://www.cnblogs.com/jason/tag/1/  			标签
https://www.cnblogs.com/jason/category/1 		分类
https://www.cnblogs.com/jason/archive/2020-11/ 		日期
  
  
  
def site(request,username,**kwargs):
    """
    :param request:
    :param username:
    :param kwargs: 如果该参数有值 也就意味着需要对article_list做额外的筛选操作
    :return:
    """
    # 先校验当前用户名对应的个人站点是否存在
    user_obj = models.UserInfo.objects.filter(username=username).first()
    # 用户如果不存在应该返回一个404页面
    if not user_obj:
        return render(request,'errors.html')
    blog = user_obj.blog
    # 查询当前个人站点下的所有的文章
    article_list = models.Article.objects.filter(blog=blog)  # queryset对象 侧边栏的筛选其实就是对article_list再进一步筛选
    if kwargs:
        # print(kwargs)  # {'condition': 'tag', 'param': '1'}
        condition = kwargs.get('condition')
        param = kwargs.get('param')
        # 判断用户到底想按照哪个条件筛选数据
        if condition == 'category':
            article_list = article_list.filter(category_id=param)
        elif condition == 'tag':
            article_list = article_list.filter(tags__id=param)
        else:
            year,month = param.split('-')  # 2020-11  [2020,11]
            article_list = article_list.filter(create_time__year=year,create_time__month=month)
    return render(request,'site.html',locals())
posted @ 2022-07-29 10:19  Edmond辉仔  阅读(68)  评论(0编辑  收藏  举报