这里是针对“Django 内置权限扩展案例详解”的完整攻略,包含两个示例说明的详细讲解。
1. 示例一
1.1 案例描述
假设我们要实现一个博客系统,需要实现以下功能:
- 所有用户都可以浏览博客列表和单篇博客。
- 未登录用户不能对博客进行任何操作(包括新建、修改、删除和点赞)。
- 登录用户可以进行以下操作:
- 创建自己的博客文章。
- 修改自己创建的博客文章。
- 删除自己创建的博客文章。
- 对任意一篇博客进行点赞。
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)
有几点需要注意:
- 使用的是Django内置的@login_required装饰器来限制用户访问需要登录的页面。
- 在blog_create视图函数中,我们使用form.save(commit=False)来创建一条未保存的博客对象,随后将博客的作者设置为request.user,并调用blog.save()来保存对象。
- 在blog_update和blog_delete视图函数中,我们使用get_object_or_404来判断用户是否有权限,同时需要通过pk和作者进行精确定位。
- 在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 案例描述
假如我们需要实现一个聊天室应用,具有以下几个要求:
- 所有用户都可以浏览当前聊天记录。
- 未登录用户不能发言。
- 登录用户可以自由发言,但是不能修改和删除其他人的聊天记录。
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技术站