代码改变世界

134-django中,多用户的复杂权限处理

2020-08-30 17:28  lzhshn  阅读(367)  评论(0编辑  收藏  举报

假设有某网站设计规则如下:

  1. 首页,过滤open_bool=True的,显示最近若干篇文章(的摘要)
  2. 我的,显示当前登录用户的所有文章(的摘要),可分页。此时的过滤是author=current_user.username;为什么这么做?因为在添加一篇文章时,会将文章绑定于当前登录用户:new_note.user = current_user,然后将文章的author属性设置为当前的登录用户的用户名:new_note.author = current_user.username
  3. 通过点击文章标题,可以进入文章页面。但之前犯了个错误,无论点击“首页”的某个标题,还是点击“我的”某个标题,都用同一个views函数和模板去处理,这是不对的!!!

 

在“/应用/函数/参数“这种url里,只改url,将会继续用同一个函数去处理,这是一类的操作。

从“首页”进,和从“我的”进,这是两种完全不一样的逻辑,区别在于:首页需要过滤open_bool条件,而我的需要过滤user条件。因此如果只用传参数来获取不同页面内容,他们应该使用不同的views函数和模板。

 

# 注意:一定是从我的点击进去的
# 为了避免直接在url里改编号,显示其他内容,还必须加上用户判断
@login_required
def one_note(request, pk):
    current_user = request.user
    pk_note = get_object_or_404(MyNote, author=current_user.username, id=pk)
    if request.method != 'POST':
        # 显示添加评论的页面
        comment_form = CommentForm()

        # 可以不用在这里用_ser.all()的方式预先得到all_comment,减少上下文传入的内容
        # 而是直接到模板里通过for comment in pk_note.comment_set.all获得,注意模板里没有()
        all_comment = pk_note.comment_set.all().order_by('-add_time')
        context = {'pk_note': pk_note, 'all_comment': all_comment, 'comment_form': comment_form}
        return render(request, 'one_note.html', context)

    else:
        form = CommentForm(request.POST)
        if form.is_valid():
            new_comment = form.save(commit=False)
            new_comment.relation_note = pk_note
            new_comment.author = current_user.username
            new_comment.save()
            pk_note.comment_num += 1
            pk_note.save()
            return HttpResponseRedirect(reverse('notebook:one_note', args=[pk]))


# 注意:一定是从首页点击进去的
# 为了避免直接在url里改编号,显示其他内容,还必须加上开放判断
@login_required
def op_one_note(request, pk):
    current_user = request.user
    pk_note = get_object_or_404(MyNote, open_bool=True, id=pk)
    if request.method != 'POST':
        comment_form = CommentForm()
        all_comment = pk_note.comment_set.all().order_by('-add_time')
        context = {'pk_note': pk_note, 'all_comment': all_comment, 'comment_form': comment_form,
                   'current_user': current_user}
        return render(request, 'op_one_note.html', context)

    else:
        form = CommentForm(request.POST)
        if form.is_valid():
            new_comment = form.save(commit=False)
            new_comment.relation_note = pk_note
            new_comment.author = current_user.username
            new_comment.save()
            pk_note.comment_num += 1
            pk_note.save()
            return HttpResponseRedirect(reverse('notebook:op_one_note', args=[pk]))

  

这两个函数对应的模板大同小异,唯独编辑的权限不一样:

    {% block content %}
    {# show a note and add a comment #}
    <div class="left">

        {# show or go to edit a note #}
        <div>
            <h3>{{pk_note.title}}</h3>
            {% if current_user.username == pk_note.author %}
                <p><a href="{% url 'notebook:edit_note' pk_note.pk %}">编辑</a></p>
            {% endif %}
            <p>作者:{{pk_note.author}} 发表:{{pk_note.pub_time}} 更新:{{pk_note.update_time}}</p>
            {% autoescape off %}
            <p>{{pk_note.content}}</p>
            {% endautoescape %}
            <p>评论数:{{pk_note.comment_num}}</p>
            <p>{{pk_note.personal_tags.all}}</p>
        </div>

        {# add a comment #}
        <div id="comment">
            <form action="{% url 'notebook:op_one_note' pk_note.pk %}" method="post">
                {% csrf_token %}
                {{comment_form.as_p}}
                <input type="submit" value="提交评论" />
            </form>

        </div>

    </div>
    {% endblock content %}

  

对于从首页点进去的情况,因为有可能看到的不是自己的文章,而筛选时只要求open_bool=True,所以必须判断仅作者等于当前用户的username时,才会显示编辑按钮;

而从我的点进去的情况,可以无需在模板里进行判断,因为它总是会过滤author=current_user.username,只会显示自己的文章,因此编辑权限一定会有。

 

这里还增加了评论作者的字段,如果对方放开了权限,则你能去他的文章下留言,文章作者是他,评论作者是你。