Django 内置权限扩展案例详解

这里是针对“Django 内置权限扩展案例详解”的完整攻略,包含两个示例说明的详细讲解。

1. 示例一

1.1 案例描述

假设我们要实现一个博客系统,需要实现以下功能:

  1. 所有用户都可以浏览博客列表和单篇博客。
  2. 未登录用户不能对博客进行任何操作(包括新建、修改、删除和点赞)。
  3. 登录用户可以进行以下操作:
  4. 创建自己的博客文章。
  5. 修改自己创建的博客文章。
  6. 删除自己创建的博客文章。
  7. 对任意一篇博客进行点赞。

1.2 解决方案

根据需求,需要对用户进行认证和授权,Django内置的权限系统可以帮助我们实现这些功能。具体实现方式如下:

1. 创建Blog模型

from django.db import models

class Blog(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    created_time = models.DateTimeField(auto_now_add=True)
    modified_time = models.DateTimeField(auto_now=True)
    like_count = models.IntegerField(default=0)

    def __str__(self):
        return self.title

其中,我们通过ForeignKey关联了User模型,确定作者权限。

2. 配置权限

在settings.py中配置权限:

INSTALLED_APPS = [
    ...
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

# 添加权限配置

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
]

LOGIN_URL = '/login/'

LOGOUT_URL = '/logout/'

LOGIN_REDIRECT_URL = '/'

3. 创建博客的视图函数

首先,我们需要在views.py中实例化Blog表单,渲染模板:

from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from .models import Blog
from .forms import BlogForm

def blog_list(request):
    blogs = Blog.objects.all()
    return render(request, 'blog/blog_list.html', context={'blogs': blogs})

def blog_detail(request, blog_id):
    blog = get_object_or_404(Blog, pk=blog_id)
    return render(request, 'blog/blog_detail.html', context={'blog': blog})

@login_required(login_url='login')
def blog_create(request):
    if request.method == 'GET':
        form = BlogForm()
    else:
        form = BlogForm(request.POST)
        if form.is_valid():
            blog = form.save(commit=False)
            blog.author = request.user
            blog.save()
            return redirect('blog_detail', blog_id=blog.id)
    return render(request, 'blog/blog_create.html', context={'form': form})

@login_required(login_url='login')
def blog_update(request, blog_id):
    blog = get_object_or_404(Blog, pk=blog_id, author=request.user)
    if request.method == 'GET':
        form = BlogForm(instance=blog)
    else:
        form = BlogForm(request.POST, instance=blog)
        if form.is_valid():
            form.save()
            return redirect('blog_detail', blog_id=blog.id)
    return render(request, 'blog/blog_update.html', context={'form': form})

@login_required(login_url='login')
def blog_delete(request, blog_id):
    blog = get_object_or_404(Blog, pk=blog_id, author=request.user)
    blog.delete()
    return redirect('blog_list')

@login_required(login_url='login')
def blog_like(request, blog_id):
    blog = get_object_or_404(Blog, pk=blog_id)
    blog.like_count += 1
    blog.save()
    return redirect('blog_detail', blog_id=blog_id)

有几点需要注意:

  1. 使用的是Django内置的@login_required装饰器来限制用户访问需要登录的页面。
  2. 在blog_create视图函数中,我们使用form.save(commit=False)来创建一条未保存的博客对象,随后将博客的作者设置为request.user,并调用blog.save()来保存对象。
  3. 在blog_update和blog_delete视图函数中,我们使用get_object_or_404来判断用户是否有权限,同时需要通过pk和作者进行精确定位。
  4. 在blog_like视图函数中增加了博客点赞的功能。

4. 创建博客的表单

针对Blog表,我们编写Blog表单:

from django import forms
from .models import Blog

class BlogForm(forms.ModelForm):
    class Meta:
        model = Blog
        fields = ['title', 'content']

5. 实现前端模板

在templates文件夹中的博客列表页blog_list.html:

{% extends 'base.html' %}

{% block content %}
    <h2>Blog List</h2>
    {% for blog in blogs %}
        <p>
            <a href="{% url 'blog_detail' blog.id %}">
                {{blog.title}}
            </a>
            <br>
            <small>
                Written by {{blog.author.username}} on {{blog.created_time}}
            </small>
            {% if request.user.username == blog.author.username %}
                <br>
                <a href="{% url 'blog_update' blog.id %}">Edit</a>
                <a href="{% url 'blog_delete' blog.id %}">Delete</a>
            {% endif %}
        </p>
    {% endfor %}
{% endblock %}

在templates文件夹中的博客详情页blog_detail.html:

{% extends 'base.html' %}

{% block content %}
    <h2>{{blog.title}}</h2>
    <p>{{blog.content}}</p>
    <small>Written by {{blog.author.username}} on {{blog.created_time}}</small>
    <br>
    {% if request.user.username == blog.author.username %}
        <a href="{% url 'blog_update' blog.id %}">Edit</a>
        <a href="{% url 'blog_delete' blog.id %}">Delete</a>
    {% endif %}
    <br>
    <form method="post" action="{% url 'blog_like' blog.id %}">
        {% csrf_token %}
        <button>Like ({{blog.like_count}})</button>
    </form>
{% endblock %}

在templates文件夹中的博客创建页blog_create.html:

{% extends 'base.html' %}

{% block content %}
    <h2>New Blog</h2>
    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Create</button>
    </form>
{% endblock %}

在templates文件夹中的博客更新页blog_update.html:

{% extends 'base.html' %}

{% block content %}
    <h2>Edit Blog</h2>
    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Update</button>
    </form>
{% endblock %}

此外,还需要创建base.html和login.html两个模版。

现在我们已经完成了第一个示例的代码实现,下面来看一下如何使用权限管理来实现第二个示例。

2. 示例二

2.1 案例描述

假如我们需要实现一个聊天室应用,具有以下几个要求:

  1. 所有用户都可以浏览当前聊天记录。
  2. 未登录用户不能发言。
  3. 登录用户可以自由发言,但是不能修改和删除其他人的聊天记录。

2.2 解决方案

根据需求,需要对用户进行认证和授权,Django内置的权限系统可以帮助我们实现这些功能。具体实现方式如下:

1. 创建Chat模型

from django.db import models
from django.contrib.auth.models import User

class Chat(models.Model):
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.content

为了实现针对聊天记录的鉴权,我们使用了ForeignKey关联了User模型,确定作者权限。

2. 配置权限

和第一个示例类似,在settings.py中配置权限:

INSTALLED_APPS = [
    ...
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

# 添加权限配置

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
]

LOGIN_URL = '/login/'

LOGOUT_URL = '/logout/'

LOGIN_REDIRECT_URL = '/'

3. 进行聊天的视图函数

在views.py中实现以下视图函数:

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import Chat

def chat_list(request):
    chats = Chat.objects.all()
    return render(request, 'chat/chat_list.html', context={'chats': chats})

@login_required(login_url='login')
def chat_create(request):
    if request.method == 'GET':
        context = {}
    else:
        content = request.POST.get('content')
        author = request.user
        Chat.objects.create(content=content, author=author)
        return redirect('chat_list')
    return render(request, 'chat/chat_create.html', context=context)

@login_required(login_url='login')
def chat_update(request, chat_id):
    chat = Chat.objects.get(pk=chat_id)

    if request.method == 'GET':
        context = {'content': chat.content}
    else:
        chat.content = request.POST.get('content')
        chat.save()
        return redirect('chat_list')

    return render(request, 'chat/chat_update.html', context=context)

@login_required(login_url='login')
def chat_delete(request, chat_id):
    Chat.objects.filter(pk=chat_id, author=request.user).delete()
    return redirect('chat_list')

其中,使用@login_required装饰器来限制用户访问需要登录的页面。在chat_create、chat_update和chat_delete视图函数中,使用了filter确保用户只能编辑自己的聊天记录。

4. 实现前端模板

在templates文件夹中的聊天记录列表页chat_list.html:

{% extends 'base.html' %}

{% block content %}
    <h2>Chat List</h2>
    <ul>
    {% for chat in chats %}
        <li>
            {{chat.content}}
            <small>
                Written by {{chat.author.username}} on {{chat.created_time}}
            </small>
            {% if request.user.username == chat.author.username %}
                <br>
                <a href="{% url 'chat_update' chat.id %}">Edit</a>
                <a href="{% url 'chat_delete' chat.id %}">Delete</a>
            {% endif %}
        </li>
    {% endfor %}
    </ul>
{% endblock %}

在templates文件夹中的聊天记录创建页chat_create.html:

{% extends 'base.html' %}

{% block content %}
    <h2>New Chat</h2>
    <form method="POST">
        {% csrf_token %}
        <label>Content:</label><br>
        <textarea name="content"></textarea>
        <br>
        <button type="submit">Submit</button>
    </form>
{% endblock %}

在templates文件夹中的聊天记录编辑页chat_update.html:

{% extends 'base.html' %}

{% block content %}
    <h2>Edit Chat</h2>
    <form method="POST">
        {% csrf_token %}
        <label>Content:</label><br>
        <textarea name="content">{{content}}</textarea>
        <br>
        <button type="submit">Submit</button>
    </form>
{% endblock %}

在templates文件夹中还需要创建一个base.html模版,作为模版继承的基础模版。值得注意的是,聊天列表页中,只有当request.user.username与chat.author.username相同时,才会出现编辑和删除按钮。

以上就是针对“Django 内置权限扩展案例详解”的完整攻略,希望能够对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django 内置权限扩展案例详解 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • 详解Django模版中加载静态文件配置方法

    当我们使用Django进行web开发时,我们常常需要加载静态文件,比如CSS样式、JavaScript脚本、图片等。在Django中,我们通常使用模版来组织和呈现我们的网页,那么如何在Django模版中加载静态文件呢? 下面是Django模版中加载静态文件配置方法的攻略: 第一步:在settings.py文件中设置静态文件路径 在django的setting…

    Django 2023年5月16日
    00
  • 使用Python的Django和layim实现即时通讯的方法

    下面我详细讲解如何使用Python的Django和layim实现即时通讯的方法。 1. 前置条件 在开始之前,你需要确保以下条件已经满足: 你已经学习了基本的Python语言知识,并且掌握了Django框架的基本使用方法。 你已经了解了layim的基本使用方法,并且理解了前后端分离的开发模式。 如果你还没有掌握以上内容,建议先进行学习和实践,然后再来阅读本文…

    Django 2023年5月16日
    00
  • 深入理解Django中内置的用户认证

    深入理解Django中内置的用户认证攻略 Django是一款非常流行的开源Web框架,可以用于构建高效且安全的Web应用程序。Django内置了用户认证系统,可以方便地实现用户登录、注册等功能。本文将深入探讨Django中内置的用户认证系统,并提供两个示例说明。 用户认证系统概述 Django中的用户认证系统是通过Django自带的auth模块实现的,该模块…

    Django 2023年5月16日
    00
  • Django_Restful_Framework

    在开发Web应用中,有两种应用模式: 前后端不分离 前后端分离 2. api接口 为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本。 目前市面上大部分公司开发人员使用的接口服务架构主要有:restful、rpc。 rpc: 翻译成中文:远程过…

    Django 2023年4月12日
    00
  • Python之Web框架Django项目搭建全过程

    下面是Python之Web框架Django项目搭建全过程的完整攻略。 1. 确定项目名称和目录结构 首先要确定项目的名称,比如”blog”,然后在命令行终端中执行以下命令: mkdir blog cd blog 进入到项目目录中。 2. 创建虚拟环境 为了避免与其他项目的依赖冲突,建议使用虚拟环境。可以使用以下命令创建一个虚拟环境: python3 -m v…

    Django 2023年5月16日
    00
  • 【django后端分离】mysql原生查询命令后,RawQueryset类型的自定义序列化返回json格式

    1:设置mysql原生分页 # 监控系统首页显示分页 def MyPagination(limitid,offsetid): limitid =str(limitid) offsetid =str(offsetid)   # 这里是mysql原生代码 show_goods = “select dal_keywordtable.* from (select a…

    Django 2023年4月12日
    00
  • on_delete django之ORM操作之Foreignkey

    on_delete指的是通过ForeignKey连接起来的对象被删除后,当前字段怎么变化。 常见的选项有:   models.CASCADE,对就对象删除后,包含ForeignKey的字段也会被删除   models.PROTECT,删除时会引起ProtectedError   models.SET_NULL,注意只有当当前字段设置null设置为True才有…

    Django 2023年4月10日
    00
  • python Django问题:TemplateDoesNotExist at /index/

       原因:发现Django1.8,设置要加载模板的路径时,不是直接自己定义一个TEMPLATE_DIR,然后给它赋值 解决:settings.py配置文件中添加红框代码   BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ‘DIRS’: [os.path.join…

    Django 2023年4月11日
    00
合作推广
合作推广
分享本页
返回顶部