在基于类的视图中限制经过身份验证的用户的“UpdateView"数据集 [英] Restrict `UpdateView` dataset for authenticated user in Class Based Views
问题描述
我有一个 Django 项目,我在其中使用 OneToOneField 扩展了用户以拥有一个配置文件.我正在使用 CBV UpdateView,它允许用户更新他们的个人资料.他们为此访问的 URL 是 ../profile/user/update.我的问题是,如果用户输入另一个用户名,他们可以编辑其他人的个人资料.如何限制 UpdateView 以便经过身份验证的用户只能更新他们的个人资料.我试图做一些事情来确保 user.get_username == profile.user 但没有运气.
模型.py
from django.db 导入模型从 django.contrib.auth.models 导入用户从 django.db.models.signals 导入 post_save从 django.core.urlresolvers 导入反向类配置文件(模型.模型):# 这是必填栏.SYSTEM_CHOICES = (('Xbox', 'Xbox'),('PS4', 'PS4'),)system = models.CharField(max_length=5,选择=SYSTEM_CHOICES,默认='Xbox')用户 = 模型.OneToOneField(用户)弹头=models.SlugField(max_length=50)gamertag = models.CharField("Gamertag", max_length=50, blank=True)f_name = models.CharField("名字", max_length=50, blank=True)l_name = models.CharField("Last Name", max_length=50, blank=True)twitter = models.CharField("Twitter 句柄", max_length=50, blank=True)video = models.CharField("YouTube URL", max_length=50, default='JhBAc6DYiys', help_text="只有扩展名!", blank=True)照片 = models.ImageField(upload_to='照片',空白 = 真)def __unicode__(self):返回 u'%s' % (self.user)def create_user_profile(sender, instance, created, **kwargs):如果创建:Profile.objects.create(用户=实例,slug=实例)post_save.connect(create_user_profile, 发件人=用户)def get_absolute_url(self):return reverse('profile-detail', kwargs={'slug': self.slug})
视图.py
from django.shortcuts 导入渲染从 django.views.generic 导入 DetailView从 django.views.generic.edit 导入 UpdateView从 django.views.generic.list 导入 ListView从profiles.models 导入配置文件类 ProfileDetail(DetailView):模型 = 简介def get_context_data(self, **kwargs):context = super(ProfileDetail, self).get_context_data(**kwargs)返回上下文类 ProfileList(ListView):模型 = 简介查询集 = Profile.objects.all()[:3]def get_context_data(self, **kwargs):context = super(ProfileList, self).get_context_data(**kwargs)返回上下文类 ProfileUpdate(UpdateView):模型 = 简介fields = ['gamertag', 'system', 'f_name', 'l_name', 'twitter', 'video', 'mugshot']template_name_suffix = '_update'def get_context_data(self, **kwargs):context = super(ProfileUpdate, self).get_context_data(**kwargs)返回上下文
管理员.py
from django.contrib import admin从模型导入配置文件类 ProfileAdmin(admin.ModelAdmin):prepopulated_fields = {'slug': ('user',), }admin.site.register(配置文件,ProfileAdmin)
个人资料应用的 Urls.py
from django.conf.urls 导入模式,url从 django.contrib.auth.decorators 导入 login_required从profiles.views 导入ProfileDetail、ProfileUpdateurlpatterns = 模式('',url(r'^(?P[-_w]+)/$', login_required(ProfileDetail.as_view()), name='profile-detail'),url(r'^(?P[-_w]+)/update/$', login_required(ProfileUpdate.as_view()), name='profile-update'),)
Profile_update.html
{% extends "base.html" %} {% load bootstrap %}{% 块内容 %}{% if user.is_authenticated %}<h1>更新您的个人资料</h1><div class="col-sm-4 col-sm-offset-4"><div class="alert alert-info alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span>按钮><strong>注意!</strong>如果您有完整的个人资料,其他用户可以更轻松地找到您.
<form enctype="multipart/form-data" method="post" action="">{% csrf_token %}{{ 表单|引导}}<input class="btn btn-default" type="submit" value="Update"/></表单>
{% 别的 %}<h1>您无法更新其他人的个人资料.</h1>{% 万一 %}{% 结束块 %}
这样的事情怎么样:
from django.contrib.auth.views import redirect_to_login类 ProfileUpdate(UpdateView):[...]def user_passes_test(self, request):如果 request.user.is_authenticated():self.object = self.get_object()返回 self.object.user == request.user返回错误def dispatch(self, request, *args, **kwargs):如果不是 self.user_passes_test(request):返回redirect_to_login(request.get_full_path())返回 super(ProfileUpdate, self).dispatch(请求,*args,**kwargs)
在本例中,用户被重定向到默认的 LOGIN_URL.但是您可以轻松更改它.将用户重定向到他们自己的个人资料.
I have a Django project where I extended the User to have a Profile using a OneToOneField. I'm using CBV UpdateView which allows users to update their profile. The URL they visit for this is ../profile/user/update. The issue I have is that if a user types in another users name they can edit the other persons profile. How can I restrict the UpdateView so the authenticated user can only update their profile. I was trying to do something to make sure user.get_username == profile.user but having no luck.
Models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.core.urlresolvers import reverse
class Profile(models.Model):
# This field is required.
SYSTEM_CHOICES = (
('Xbox', 'Xbox'),
('PS4', 'PS4'),
)
system = models.CharField(max_length=5,
choices=SYSTEM_CHOICES,
default='Xbox')
user = models.OneToOneField(User)
slug = models.SlugField(max_length=50)
gamertag = models.CharField("Gamertag", max_length=50, blank=True)
f_name = models.CharField("First Name", max_length=50, blank=True)
l_name = models.CharField("Last Name", max_length=50, blank=True)
twitter = models.CharField("Twitter Handle", max_length=50, blank=True)
video = models.CharField("YouTube URL", max_length=50, default='JhBAc6DYiys', help_text="Only the extension!", blank=True)
mugshot = models.ImageField(upload_to='mugshot', blank=True)
def __unicode__(self):
return u'%s' % (self.user)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance, slug=instance)
post_save.connect(create_user_profile, sender=User)
def get_absolute_url(self):
return reverse('profile-detail', kwargs={'slug': self.slug})
Views.py
from django.shortcuts import render
from django.views.generic import DetailView
from django.views.generic.edit import UpdateView
from django.views.generic.list import ListView
from profiles.models import Profile
class ProfileDetail(DetailView):
model = Profile
def get_context_data(self, **kwargs):
context = super(ProfileDetail, self).get_context_data(**kwargs)
return context
class ProfileList(ListView):
model = Profile
queryset = Profile.objects.all()[:3]
def get_context_data(self, **kwargs):
context = super(ProfileList, self).get_context_data(**kwargs)
return context
class ProfileUpdate(UpdateView):
model = Profile
fields = ['gamertag', 'system', 'f_name', 'l_name', 'twitter', 'video', 'mugshot']
template_name_suffix = '_update'
def get_context_data(self, **kwargs):
context = super(ProfileUpdate, self).get_context_data(**kwargs)
return context
Admin.py
from django.contrib import admin
from models import Profile
class ProfileAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('user',), }
admin.site.register(Profile, ProfileAdmin)
Urls.py for Profiles app
from django.conf.urls import patterns, url
from django.contrib.auth.decorators import login_required
from profiles.views import ProfileDetail, ProfileUpdate
urlpatterns = patterns('',
url(r'^(?P<slug>[-_w]+)/$', login_required(ProfileDetail.as_view()), name='profile-detail'),
url(r'^(?P<slug>[-_w]+)/update/$', login_required(ProfileUpdate.as_view()), name='profile-update'),
)
Profile_update.html
{% extends "base.html" %} {% load bootstrap %}
{% block content %}
{% if user.is_authenticated %}
<h1>Update your profile</h1>
<div class="col-sm-4 col-sm-offset-4">
<div class="alert alert-info alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong>Heads up!</strong> Other users can find you easier if you have a completed profile.
</div>
<form enctype="multipart/form-data" method="post" action="">{% csrf_token %}
{{ form|bootstrap }}
<input class="btn btn-default" type="submit" value="Update" />
</form>
</div>
{% else %}
<h1>You can't update someone elses profile.</h1>
{% endif %}
{% endblock %}
How about something like this:
from django.contrib.auth.views import redirect_to_login
class ProfileUpdate(UpdateView):
[...]
def user_passes_test(self, request):
if request.user.is_authenticated():
self.object = self.get_object()
return self.object.user == request.user
return False
def dispatch(self, request, *args, **kwargs):
if not self.user_passes_test(request):
return redirect_to_login(request.get_full_path())
return super(ProfileUpdate, self).dispatch(
request, *args, **kwargs)
In this example, the user is redirected to default LOGIN_URL. But you can easily change it . to redirect user to their own profile.
这篇关于在基于类的视图中限制经过身份验证的用户的“UpdateView"数据集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!