为Pythonic论坛添加一个“专题”功能

代码还没读完就踏上了修改功能的深坑。还好思路清晰,通过修改模板和视图,实现了专题模块

原论坛的模式是用户点击节点发帖,然后就归到节点的分类里面了。我需要一个功能,就是右侧需要一个专题区,管理员发帖的话需要显示在那里。为了尽量小的修改实现功能,我决定设置一个管理员节点,然后在视图调用数据库过滤出节点,就可以了。

------

那么问题出现了,既然是节点,所有用户都可以点击节点发帖,这岂不乱了?

于是,我打起了发帖框的主意,如果能使用什么方法,使普通用户点击这个节点时不显示发帖框,管理员点击显示发帖框,从而就实现了对一般用户隐藏,达成目的。所以我翻看了模板。原模板如下:

{% if user.is_authenticated %}
<div class="box">
    <form action="/node/{{node.slug}}/create" method="post" class="form-vertical" onSubmit="return beforeSubmit(this);"> {% csrf_token %}
        {% for field in form %}
        <div class="control-group">
            <label class="control-label">{{ field.label_tag }}</label>
            <div class="controls">
                {{ field }}
            </div>
            <label>{{ field.errors }}</label>
        </div>
        {% endfor %}
        </table>
        <div class="control-group">
            <div class="controls" style="margin-left: 0;float:right;">
                <input type="submit" value="创建" class="btn btn-success">
            </div>
        </div>
    </form>
</div>
{% else %}
<div class="required">您需要 <a style="height: 20px;line-height:20px;" href="/accounts/login">登录</a> 来发表新话题。没有账号,马上 <a style="height: 20px;line-height:20px;" href="/accounts/register">注册</a> 一个。</div>
{% endif %}

翻看用户的方法和模板的一些控制语句。找到了user.is_staffifnotequal两个很有用的东东。通过一些逻辑组合,就变成了如下的代码,实现了当用户未登录时显示请登录,登陆后如果是普通用户,在指定的父节点下,则不显示发帖框,如果是管理员则显示。

is_staff()可以判断用户是否可以登录后台

{% if user.is_authenticated %}
    {% if user.is_staff %}
    <div class="box">
        <form action="/node/{{node.slug}}/create" method="post" class="form-vertical" onSubmit="return beforeSubmit(this);"> {% csrf_token %}
            {% for field in form %}
            <div class="control-group">
                <label class="control-label">{{ field.label_tag }}</label>
                <div class="controls">
                    {{ field }}
                </div>
                <label>{{ field.errors }}</label>
            </div>
            {% endfor %}
            </table>
            <div class="control-group">
                <div class="controls" style="margin-left: 0;float:right;">
                    <input type="submit" value="创建" class="btn btn-success">
                </div>
            </div>
        </form>
    </div>
    {% else %}
        {% ifnotequal node.category.name ‘父节点名称‘ %}
        <div class="box">
            <form action="/node/{{node.slug}}/create" method="post" class="form-vertical" onSubmit="return beforeSubmit(this);"> {% csrf_token %}
                {% for field in form %}
                <div class="control-group">
                    <label class="control-label">{{ field.label_tag }}</label>
                    <div class="controls">
                        {{ field }}
                    </div>
                    <label>{{ field.errors }}</label>
                </div>
                {% endfor %}
                </table>
                <div class="control-group">
                    <div class="controls" style="margin-left: 0;float:right;">
                        <input type="submit" value="创建" class="btn btn-success">
                    </div>
                </div>
            </form>
        </div>
        {% endifnotequal %}
    {% endif %}
{% else %}
<div class="required">您需要 <a style="height: 20px;line-height:20px;" href="/accounts/login">登录</a> 来发表新话题。没有账号,马上 <a style="height: 20px;line-height:20px;" href="/accounts/register">注册</a> 一个。</div>
{% endif %}

这样,templates部分的node.html模板功能就实现了。(这是点击节点后的显示模板)
还有一部分是首页index.html,主界面的部分也需要修改,因为原先有热门话题模块,所以可以很方便的拿来修改。

{% if special_topics %}
<div class="box">
    <h4>专题</h4><hr class="line thin"/>
    {% for item in special_topics %}
    <div class="cell">
        <table cellpadding="0" cellspacing="0" border="0" width="100%">
            <tbody><tr>
            <td width="24" valign="middle" align="center">
                <a href="/people/{{item.author.get_profile.slug}}" title="{{ item.author.get_profile.name}}"><img src="/media/avatar/{{ item.author.get_profile.avatar }}" class="avatar" border="0" style="max-width: 24px; max-height: 24px;" alt="{{ item.author.get_profile.name}}"></a>
            </td>
            <td width="10"></td>
            <td width="auto" valign="middle">
                <span class="hot_topic_title">
                    <a href="/topic/{{item.id}}" title="{{item.title}}">{{item.title}}</a>
                </span>
            </td>
        </tr>
        </tbody></table>
    </div>
    {% endfor %}
    <div class="clearfix"></div>
</div>
{% endif %}

上面原本的hot_topics已经被我替换成special_topics,至于这个special_topics,就需要使用views视图来定义了。
打开site目录的views模块。看见如下的一些代码:

hot_topics = Topic.objects.filter(created_on__range=[from_date, time_now]).order_by(‘-num_replies‘)[:10]
context[‘hot_topics‘] = hot_topics
hot_nodes = Node.objects.filter(num_topics__gt=0,updated_on__gt=from_date).order_by(‘-updated_on‘)[:10]
context[‘hot_nodes‘] = hot_nodes
return render(request,‘index.html‘,context)

这样,通过定义context处理器实现了替换,只需要添加special_topics变量即可。获取指定的节点的数据。在模板中就可以显示了。
在Topic类下有node变量,外键是Node主题帖的节点,Node中有slug属性。这样就可以过滤出节点slug为“zt”的节点的所有主题帖。添加如下代码。

special_topics = Topic.objects.filter(node__slug__iexact="zt").order_by(‘-num_replies‘)[:10]
context[‘special_topics‘] = special_topics

OK,使用管理员登陆,发帖,刷新,首页出现了“专题”模块。

————————-

吐槽:某度的搜索真心浪费时间,最开始使用node.slug出错,想找找使用外键的例子。就是出不来。

最后使用了基于Google的一个搜索,马上发现node.slug应该写成node__slug。纠结了好半天!

时间: 2024-08-02 19:03:15

为Pythonic论坛添加一个“专题”功能的相关文章

为Pythonic论坛添加一个“专题”功能(续)

上篇博文<为Pythonic论坛添加一个“专题”功能>,在模板的层次上对发帖进行了限制.也就是根据用户是否拥有权限来决定是否显示发帖框. 但是自从这么“投机取巧”的写完模板后,整夜辗转反侧,不知道用户能否通过其它节点在不能够发帖的节点本地添加发帖框实现发帖. 最终,我还是觉得不靠谱…需要在服务端也进行下验证.简单的处理,终于填了坑 翻看\apps\topic\views.py文件找到def topic_create(request, node_slug):函数定义. if node.categ

不能因为为了添加一个新功能,影响到旧的功能

涉及到后台的, 一般都是要跟数据库打交道的大型数据量的处理问题.以类 client - server 为基础的架构, 或者变形后的架构. 客户端处理用户的输入和数据, 然后大量的客户端(多个客户端的多种数据) 反馈到服务端统一处理和协调, 然后服务端对客户端发出相应的指令.其中 后台程序 代表的就是服务端的程序. 包含以下几点:1. 网络通信,  要跟远程的client打交道,只能用网络2. 并发 和 并行处理.0.. 多个客户端可能在同一时间同时需要处理同一个类型的数据, 谁先谁后,谁的有效谁

UITextView添加一个placeholder功能

控件UITextField有个placeholder属性,UITextField和UITextView使用方法基本类似,有两个小区别:1.UITextField单行输入,而UITextView可以多行输入.2.UITextField有placeholder属性,而UITextView没有.至于两者的代理方法,原理基本差不多,只是方法名略有差异. 实现该功能有两种方式 一种是 ①使用通知 显示隐藏遮盖物 ②使用代理 给文本框重新赋值 1.在创建textView的时候,赋值其文本属性 即textVi

为Unity开发的android手机游戏添加一个社会化分享功能

先看一下我最近自己做的一个游戏的效果图,然后在为大家讲述怎么做这样一个分享功能,如果图片不直观,当然如果你也不介意我顺便宣传一下我的游戏,你可以点击以下这个链接,下载我的游戏,进去体验一下里面的这个分享功能:http://zhushou.360.cn/detail/index/soft_id/2954399?recrefer=SE_D_BubbleDeer 好了,接下来我们就来一起探讨一下这个分享功能怎么做. (1)提供下载一个社会化分析的SDK,这个我用的是mob.com网的ShareSDK,

在GridView里添加一个功能按钮

标题描述的不是特别清楚,其实最直接明了的就是看一张图 在这幅图里,主要的布局就是一个GridView组件,拍摄照片是个相当于一个按钮的组件,然后其他的内容都是一张张图片,如果单独为了添加一个按钮而自定义个组件,那么是很费劲的! 正常情况下,使用GridView,效果是这样的' 如果实现和微信界面类似的效果,怎么办呢? 主要修改点在GridView的BaseAdapter里,修改它就能实现微信的效果了.其它部分就不着重说明了,主要说明这个BaseAdapter 首先需要思考,GridView的数据

为 JS 的字符串,添加一个 format 的功能。

<script> String.prototype.format = function (kwargs) { var ret = this.replace(/\{(\w+)\}/g, function (substring, args) { return kwargs[args] }); } </script> js 中是没有 format 这种格式化的方法的. 但是 因为字符串也是一个原型类,所有的方法都在  prototype中. 所以可以向这个里面添加一个 自定义的 form

添加顶踩功能

phpcms如何添加顶踩功能步骤: 1.在后台模型增加两个字段,一个goodpost,一个badpost;这个步骤简单,按后台新增加字段下一步就行了. 2.在模块/phpcms/modules/content/增加扩展函数newindex.php,代码如下: <?php defined('IN_PHPCMS') or exit('No permission resources.'); class newindex{ function __construct(){ $this->db=pc_ba

使用EasyUI实现添加和删除功能

        增删该查是任何一个项目都少不了的功能操作,这篇博文主要简介一下如何使用EasyUI实现添加和删除功能.         首先,导入EasyUI的js代码: <link href="~/EasyuiSource/themes/default/easyui.css" rel="stylesheet" /> <link href="~/EasyuiSource/themes/icon.css" rel="st

用汇编语言给XP记事本添加“自动保存”功能 good

[文章标题]: 用汇编语言给XP记事本添加“自动保存”功能 [文章作者]: newjueqi [作者邮箱]:[email protected] [作者QQ]:190678908 [使用工具]: OD, LordPE,eXeScope[操作平台]: XP-SP2[作者声明]: 本人平时一般的文字处理都是用记事本(用Word好像大材小用了),电脑自从拿去大修后有时候会莫名其妙的重启,弄得经常重写(本人常常忘记保存^-^),于是想给记事本增加类似于Word的自动保存功能,以图个方便.失误之处敬请诸位大