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 项目中的模板文件变得越来越多,结构越来越复杂时,优化模板结构变得尤为重要。下面是 Django 模板结构优化的方法。 1. 组织模板文件夹 将模板文件按照功能或模块划分到不同的文件夹中,让整个模板文件夹保留良好的结构和层次,使得模板文件在维护和更新时更加方便。例如,可以按照视图的功能划分文件夹,或者按照页面的类型划分文件夹: templ…

    Django 2023年5月16日
    00
  • Django实现自定义标签

    在Django中,标签(Tag)是一种用于添加动态数据和逻辑的模板语言。标签能够实现复杂的逻辑,并且使模板变得更加灵活。 Django提供了一些内置的标签,但是有时候我们需要自定义标签,以满足特定的需求。 Django提供了两种自定义标签的方式:简单标签和复杂标签。简单标签是没有结束标记的标签,而复杂标签有开始标记和结束标记。 简单标签 自定义简单标签只需要…

    Django 2023年3月12日
    00
  • Django项目-创建第一个页面

    创建了blog应用后,再创建页面 1.编辑应用blog下的views.py   每个响应对应一个函数,函数必须返回一个响应   函数必须存在一个参数,一般约定为request   每一个响应对应一个URL    from django.http import HttpResponse def index(request):   return HttpResp…

    2023年4月10日
    00
  • Django开发过程中遇到的问题和解决方案

    1.django向数据库中添加中文时报错 解决方案:创建数据库的时候设置编码格式 2.django的信号使用无法触发信号里的内容 解决方案:在django 1.7后,使用信号时候需要在应用配置类中的ready() 方法中连接。所以我们需要配置先ready()需要在以下两个地方写入配置需要在项目的app.py,init.py两个文件中写入配置 3.django…

    Django 2023年4月12日
    00
  • 详解Django Model继承模型

    Django Model继承模型是一种常用的模型设计方式,可以减少重复的代码,提高代码的可维护性。 本篇文章将详细介绍Django Model继承模型的完整攻略,包括继承模型的类型、实现继承模型的方法和示例代码。 继承模型类型 Django Model继承模型主要分为三种类型: (1) 单表继承 单表继承,也称为表里继承或者全在一个表里的继承,是指子类和父类…

    Django 2023年3月12日
    00
  • 详解如何用django实现redirect的几种方法总结

    下面是关于“详解如何用Django实现redirect的几种方法总结”的攻略: 1. 使用redirect()函数 在Django中实现redirect最简单的方法就是使用redirect()函数。 1.1 redirect()函数的语法 redirect()函数的语法如下: redirect(to, *args, permanent=False, **kw…

    Django 2023年5月16日
    00
  • [TimLinux] django html如何实现固定表头

    表格很长,这个时候就希望表格头部不动,而只是表格内容行支持滚动功能。 2. 方法 两张表:一张表(THeader)负责头部字段的显示,另一张表(TBody)负责内容行字段的显示。 两张表都存放在一个div中 THeader、TBody分别存放在一个div中 整个div不支持滚动条:overflow: hidden 包住TBody的div支持滚动条:overf…

    Django 2023年4月13日
    00
  • Django-基本命令

    打开 Linux 或 MacOS 的 Terminal (终端)直接在 终端中输入这些命令(不是 python 的 shell中) 如果是 windows 用 cmd(开始 搜索 cmd 或者 快捷键 win + R,输入 cmd) 直接在 cmd 上操作。 1. 新建一个 django project django-admin.py startprojec…

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