Django - BBS - 项目学习 - 个人站点的实现

目录

一、路由配置

二、视图函数

三、前端设计

3-1 母版

3-2 自定义过滤器(inclusion_tag)

3-3 配合inclusion_tag使用结构页(classify.html)

3-4 继承子版(new_user_blog.html)


一、路由配置

from django.conf.urls import url
from django.contrib import admin
from bbs import views

from django.views.static import serve
from mybbs.settings import MEDIA_ROOT

urlpatterns = [
    url(r'^$', views.index),

    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    # 用于login前端页面对于验证码的获取
    url(r'^get_valid_code/', views.get_valid_code),

    url(r'^index/', views.index),
    url(r'^register/', views.register),
    url(r'^logout/', views.logout),
    url(r'^change_pwd/', views.change_pwd),
    url(r'^change_avatar/', views.change_avatar),

    url(r'^media/(?P<path>.*)', serve, {"document_root": MEDIA_ROOT}),


    # 三个过滤(分类,标签,归档) - 用于进入点击左边导航后的个人站点的文章显示
    # 分组分出三个(用户名,category|tag|archive中的一个,可能是分类id,tag_id,时间)
    url(r'^(?P<username>[\w]+)/(?P<condition>category|tag|archive)/(?P<param>.*)', views.user_blog),
    # 个人主页的文章查看路由
    url(r'^(?P<username>[\w]+)/article/(?P<id>\d+)', views.article_detail),

    # 上方未匹配到,接收参数匹配个人站点 有名分组
    url(r'^(?P<username>[\w]+)$', views.user_blog),

]

二、视图函数

from django.shortcuts import render, HttpResponse, redirect
from bbs import models
from django.db.models import Count
from django.db.models.functions import TruncMonth

# -----------个人站点(分类文章显示)----------
def user_blog(request, username, *args, **kwargs):
    '''
    个人站点(参数需要与路由的有名分组进行对应)
        - 用于获取用户的所有文章及简单信息
        - 可以通过左侧导航控制显示的文章数和文章信息
        - 通过模板的导入和继承实现
        - 左侧时间导航切割显示 - TruncMonth模块
    :param request:
    :param username:
    :return:
    '''
    user = models.UserInfo.objects.filter(username=username).first()
    if not user:
        return render(request, 'error.html')
    blog = user.blog
    # 获取当前blog站点对象。Category分类表下的article文章数
    category_num = models.Category.objects.all().filter(blog=blog).annotate(coun=Count('article__title')).values_list(
        'title', 'coun', 'pk')
    print(category_num)  # <QuerySet [('编程基础', 2), ('计算机基础', 0)]>
    # 获取当前blog站点对象,Tag标签表下的article文章数
    tag_num = models.Tag.objects.all().filter(blog=blog).annotate(coun=Count('article__title')).values_list('title',
                                                                                                            'coun',
                                                                                                            'pk')
    print(tag_num)  # <QuerySet [("test's tag 1", 0), ("test's tag 2", 0)]>

    # 获取当前blog站点对象,按年月分类的文章数 - TruncMonth模块
    y_m_num = models.Article.objects.all().filter(blog=blog).annotate(y_m=TruncMonth('create_time')).values(
        'y_m').annotate(coun=Count('y_m')).values_list('y_m', 'coun').order_by('-y_m')
    print(y_m_num)  # <QuerySet [(datetime.datetime(2018, 11, 1, 0, 0), 2)]>

    # 获取当前站点的所有文章对象 - 一对多反向查询,表名小写_set
    article_list = blog.article_set.all()
    # 获取从前端传来的关键词进行逻辑操作
    condition = kwargs.get('condition')
    param = kwargs.get('param')
    if param:
        if 'tag' == condition:
            # 当点入标签内,查询文章对象符合标签主键为url传输id的对象
            article_list = article_list.filter(tag__pk=param)
        elif 'category' == condition:
            # 当点入分类内,查询文章对象符合分类主键为url传输id的对象
            article_list = article_list.filter(category__pk=param)
        elif 'archive' == condition:
            # 当点入随笔时间内,查询文章对象符合创建时间为url传输时间的对象
            # url内传输数据2018-11 切分[2018,11]
            archive_list = param.split('-')
            # 过滤:发布年为2018年,月为11月的所有文章
            article_list = article_list.filter(create_time__year=archive_list[0], create_time__month=archive_list[1])
    return render(request, 'new_user_blog.html', locals())

三、前端设计

3-1 母版

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {# blog对象的反向查询 表名小写#}
    <title>{{ blog.userinfo.username }}-的个人博客</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    {# 使用当前用户的样式文件 #}
    <link rel="stylesheet" href="/static/css/{{ blog.theme }}">
    <link rel="stylesheet" href="/static/css/default.css">

    <script src="/static/jquery-3.3.1.js"></script>

    <style>
        * {
            margin: 0;
            padding: 0;
        }

    </style>
</head>
<body>
<div class="head">
    <h1>{{ blog.title }}</h1>
</div>
<div class="container-fluid">
    <div class="row">
        {# 侧栏导航 模板的导入#}
        <div class="col-md-3">
            {# 也可以通过自定义过滤器进行互相传参操作#}
            {% load my_tag %}
            {% classify username %}
            {#            通过模板导入具有的局限性:每个视图函数内必须返回所需的参数才能构建一个网站#}
            {#            {% include 'classify.html' %}#}
        </div>
        {# 中心内容 模板的继承#}
        <div class="col-md-9">
            {% block content %}
            {% endblock %}
        </div>
    </div>
</div>
</div>
</body>
</html>

3-2 自定义过滤器(inclusion_tag)

from django.template import Library
from django.db.models.functions import TruncMonth
from bbs import models
from django.db.models import Count

register = Library()


@register.inclusion_tag('classify.html')
def classify(username):
    user = models.UserInfo.objects.filter(username=username).first()
    blog = user.blog
    category_num = models.Category.objects.all().filter(blog=blog).annotate(coun=Count('article__title')).values_list(
        'title', 'coun', 'pk')
    tag_num = models.Tag.objects.all().filter(blog=blog).annotate(coun=Count('article__title')).values_list('title',
                                                                                                            'coun',
                                                                                                            'pk')
    y_m_num = models.Article.objects.all().filter(blog=blog).annotate(y_m=TruncMonth('create_time')).values(
        'y_m').annotate(
        coun=Count('y_m')).values_list('y_m', 'coun')

    return {'category_num': category_num, 'tag_num': tag_num, 'y_m_num': y_m_num, 'username': username}

3-3 配合inclusion_tag使用结构页(classify.html)

<div>
    <div class="panel panel-primary">
        <div class="panel-heading">我的标签</div>
        <div class="panel-body">
            {% for foo in tag_num %}
                {# <p><a href="tag/{{ foo.2 }}">{{ foo.0 }}({{ foo.1 }})</a></p>#}
                <p><a href="/{{ username }}/tag/{{ foo.2 }}">{{ foo.0 }}({{ foo.1 }})</a></p>
            {% endfor %}
        </div>
    </div>

    <div class="panel panel-primary">
        <div class="panel-heading">我的分类</div>
        <div class="panel-body">
            {% for foo in category_num %}
                <p><a href="/{{ username }}/category/{{ foo.2 }}">{{ foo.0 }}({{ foo.1 }})</a></p>
            {% endfor %}

        </div>
    </div>

    <div class="panel panel-primary">
        <div class="panel-heading">随笔档案</div>
        <div class="panel-body">
            {% for foo in y_m_num %}
                {# 注意:a标签内链接对时间的修改,href内必须传输和后台的处理一一对应#}
                <p><a href="/{{ username }}/archive/{{ foo.0|date:"Y-m" }}">{{ foo.0|date:"Y年m月" }}({{ foo.1 }})</a></p>
            {% endfor %}

        </div>
    </div>
</div>

3-4 继承子版(new_user_blog.html)

{% extends 'base.html' %}
{% block content %}


    {#通过站点查询所有文章,反向查询,按表名小写_set.all#}
    {% for article in article_list %}
        {#lqz/article/1#}
        <h4><a href="/{{ username }}/article/{{ article.pk }}">{{ article.title }}</a></h4>
        <div>
            {{ article.desc }}
        </div>
        {# clearfix是bootstrap框架提供的清浮动方式 #}
        <div class="clearfix">
            <div style="margin-top: 10px " class="article_bottom small pull-right">
                <span>posted @ {{ article.create_time|date:'Y-m-d H:i:s' }}</span>
                {#反向查询,一对多,按表名小写_set#}
                {# <span class="glyphicon glyphicon-comment"><a href="">评论({{ article.commit_num }})</a></span>#}

                <span>{{ article.blog.userinfo.username }}</span>
                <span><i class="fa fa-comment" aria-hidden="true"><a
                        href="">评论({{ article.commit_num }})</a></i></span>

                {# <span class="glyphicon glyphicon-comment"><a href="">评论({{ article.commit_num }})</a></span>#}
                <span class="glyphicon glyphicon-thumbs-up"><a href="">点赞({{ article.up_num }})</a></span>
                <span><a href="">编辑</a></span>
            </div>
        </div>
        <hr>
    {% endfor %}

{% endblock %}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要搭建一个django-vue-admin项目,你可以按照以下步骤进行操作: 1. 首先,创建一个Django项目,并安装所需的依赖。在设置文件中,确保你的TEMPLATES配置中包含了以下内容:'BACKEND': 'django.template.backends.django.DjangoTemplates'。 2. 接下来,配置Django的模板上下文处理器。在设置文件中,确保你的TEMPLATES配置中包含了以下内容:'django.contrib.auth.context_processors.auth'和'django.template.context_processors.request'。 3. 然后,安装django-vue-admin库。你可以使用pip安装它:pip install django-vue-admin。 4. 在你的Django项目中创建一个新的应用程序。你可以使用以下命令创建一个名为"admin"的应用程序:python manage.py startapp admin。 5. 在你的项目设置文件中注册新创建的应用程序。将'app名'admin'添加到你的INSTALLED_APPS配置中。 6. 在admin应用程序的目录中创建一个名为"templates"的文件夹,并在其中创建一个名为"admin"的子文件夹。 7. 在"admin"文件夹中创建一个名为"base.html"的模板文件,该文件将作为你的项目的基础模板。 8. 在"base.html"模板文件中,使用Vue.js编写前端代码,以实现你希望在项目中看到的功能和样式。 9. 在你的admin应用程序的视图中,定义需要的后端逻辑和模型操作。 10. 最后,运行你的Django服务器并访问项目的URL,以查看django-vue-admin项目的效果。 请按照以上步骤进行操作,你就可以成功地搭建一个django-vue-admin项目了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Django+Vue环境搭建](https://blog.csdn.net/WeirdoGiraffe/article/details/124863602)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值