• amin后台管理, media文件夹资源开放, 个人站点页面搭建, 侧边栏筛选


    django admin后台管理

    Xadmin组件: 参照django admin而来

    如何使用django admin后台管理

    1. 在app01中的admin.py中注册想要管理的模型类(表)
    2. 注册超级用户: python admin.py createsuperuser
    3. admin会自动给所有注册了的模型表加一个s后缀
    4. admin会通过url(r'^admin/', admin.site.urls),语句, 给注册了的模型表自动生成增删改查四条url,
    5. 路由分发本质: url函数嵌套
    # app01-->admin.py
    from django.contrib import admin
    from app01 import models
    
    # Register your models here.
    admin.site.register(models.UserInfo)
    
    '''
    # 设置django admin后台表名显示
    class UserInfo(AbstractUser):
        ...
    
        class Meta:
            verbose_name_plural = '用户表'  # 显示结果: 用户表
            # verbose_name = '用户表'  # 显示结果: 用户表s
    '''
    

    数据录入

    phone = models.BigIntegerField(null=True, blank=True) # blank告诉admin后台管理中的phone可以为空, 不会影响数据库, 不需要执行迁移命令

    文章表: 分类, 个人站点

    用户和个人站点

    文章与分类的关系

    '''
    {% for article_obj in article_queryset %}
        <div class="media">
            <h4 class="media-heading"><a href="">{{ article_obj.title }}</a></h4>  # 标题
            <div class="media-left media-middle">
                <a href="#">
                    <img class="media-object" src="/static/img/default.jpg" alt="..." height="60">  # 图片
                </a>
            </div>
            <div class="media-body">
                {{ article_obj.digest }}  # 摘要
            </div>
            <br>
            {#                    北京老雷 发布于 2019-12-10 21:09 评论(0)阅读(0)#}
            <div>
                <span><a href="">{{ article_obj.blog.userinfo.username }}&nbsp;&nbsp;</a></span>  # 文章表跨到站点表跨到用户表查询用户名
                <span>发布于&nbsp;&nbsp;</span>
                <span>{{ article_obj.create_time|date:'Y-m-d' }}&nbsp;&nbsp;</span>  # 筛选器展示文章表中的创建时间
                <span><span class="glyphicon glyphicon-comment"></span>评论({{ article_obj.comment_num }})&nbsp;&nbsp;</span>
                <span><span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article_obj.up_num }})</span>
            </div>
        </div>
        <hr>
    {% endfor %}
    '''
    

    MEDIA用户配置及文件资源开放

    网站所用到的静态文件统一放在static文件夹下

    用户上传的静态文件也要用一个统一的文件夹存储

    '''
    # MEDIA用户配置: 能够将用户上传的所有静态文件统一放到指定的文件夹下
    # settings.py
    MEDIA_ROOT = os.path.join('media')  # media文件夹-->avatar文件夹(upload_to参数控制)
    
    # urls.py
    ...
    from BBS import settings
    from django.views.static import serve
    
    urlpatterns = [
        ...
        url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),  # 固定写法, 将media文件夹的资源向外界开放
        # url(r'^app01/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),
        # MEDIA_ROOT = os.path.join('app01'), # http://127.0.0.1:8000/app01/views.py/, 开放app01文件夹的资源
    ]
    '''
    

    图片防盗链

    通过判断GET请求中的referer参数中的前缀url, 如果是本网站, 那么正常访问, 否则禁止

    GET请求中的user-agent参数用来标识是否为浏览器

    个人站点页面搭建

    '''
    # urls.py
    url(r'^(?P<username>w+)/$', views.site, name='username'),
    
    # site.html
    <head>
        ...
        <link rel="stylesheet" href="/media/css/{{ user_obj.blog.site_theme }}">  <!--引入用户上传的css样式文件-->
    </head>
    '''
    

    文章展示及侧边栏分类筛选

    '''
    # urls.py
    from app01 import views
    from django.views.static import serve
    
    urlpatterns = [
       ...
        url(r'^(?P<username>w+)/$', views.site, name='username'),
        # url(r'^(?P<username>w+)/category/(?P<param>d+)/', views.site),
        # url(r'^(?P<username>w+)/tag/(?P<param>d+)/', views.site),
        # url(r'^(?P<username>w+)/archive/(?P<param>w+)/', views.site),
    
        # 正则表达式优化
        url(r'^(?P<username>w+)/(?P<condition>category|tag|archive)/(?P<param>.*)/', views.site)  # .*为贪婪模式(最大跨度)
    ]
    
    # views.py
    def site(request, username, **kwargs):
        user_obj = models.UserInfo.objects.filter(username=username).first()  # username由home页面对应的a标签发GET请求时传入
        if not user_obj:
            return render(request, 'error.html')  # 返回404报错页面
    
        blog = user_obj.blog  # <class 'app01.models.Blog'>, blog为一个blog对象
    
        article_list = models.Article.objects.filter(blog=blog)  # 筛选出个人站点中所有文章
    
        if kwargs:
            condition = kwargs.get('condition')  # condition为对应的a标签发GET请求时, src参数中表示筛选类别的第二段url
            param = kwargs.get('param')  # param为对应的a标签发GET请求时, src参数中表示筛选条件的第三段url
    
            if condition == 'category':
                article_list = article_list.filter(category_id=param)
            elif condition == 'tag':
                article_list = article_list.filter(tag__id=param)
            else:
                year, month = param.split('-')  # 2019, 10
                article_list = article_list.filter(create_time__year=year, create_time__month=month)
    
        category_list = models.Category.objects.filter(blog=blog).annotate(num=Count('article')).values_list('name', 'num', 'pk')
        # <QuerySet [('jason的分类一', 2, 1), ('jason的分类二', 1, 2), ('jason的分类三', 1, 3)]>, 后两个数字分别为该分组下的数量和主键
    
        tag_list = models.Tag.objects.filter(blog=blog).annotate(num=Count('article')).values_list('name', 'num', 'pk')
        # <QuerySet [('jason的标签一', 1, 1), ('jason的标签二', 2, 2), ('jason的标签三', 2, 3)]>, 后两个数字分别为该分组下的数量和主键
    
       date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time'), num=Count('pk')).values_list('month', 'num')
        # <QuerySet [(datetime.date(2019, 10, 1), 1), ...]>, 分别为日期, 数量, 用不到主键
    
        return render(request, 'site.html', locals())
        
    # site.html
    {% for category in category_list %}  # 渲染文章标签
    	<p><a href="/{{ username }}/category/{{ category.2 }}/{{ category.pk }}">{{ category.0 }} ({{ category.1 }})</a></p>
    {% endfor %}
    
    {% for tag in tag_list %}  # 渲染文章分类
    	<p><a href="/{{ username }}/tag/{{ tag.2 }}">{{ tag.0 }} ({{ tag.1 }})</a></p>
    {% endfor %}
    
    {% for date in date_list %}  # 渲染日期归档
    	<p><a href="/{{ username }}/archive/{{ date.0|date:'Y-m' }}">{{ date.0|date:'Y年m月' }} ({{ date.1 }})</a></p>
    {% endfor %}
    # date.0|date:'Y-m', 日期筛选器控制a标签发GET请求时第三段url的参数格式
    '''
    
  • 相关阅读:
    keepalived.conf配置说明
    监控端口是否开放,端口未开放关闭虚拟ip,端口开放启动虚拟IP
    lvs UDP端口负载均衡配置
    keepalived自动安装脚本
    Keepalived+LVS实现高可用负载均衡双主模式
    cookie和session的区别
    jmeter 关联
    浏览器缓存详解:expires,cache-control,last-modified,etag详细说明
    Session、Cookie、Cache、Token分别是什么及区别
    获取MyBatis
  • 原文地址:https://www.cnblogs.com/-406454833/p/12025047.html
Copyright © 2020-2023  润新知