在我的项目中,我有不同类型的用户:
User
|-Client
|-Employee
|-Technical Manager
|-Service Manager
|-Production Manager
没有用户可以url
访问其他用户的视图。客户端无法通过为技术经理的个人资料分配的网址/officer/profile
访问技术经理的个人资料。
为了做到这一点,在我Client class
的{{1}}中,我使用了这段代码:
models.py
然后对于每个视图,我使用了这样的装饰器:
class Client(models.Model):
class Meta:
permissions = (
('view_client', 'view_Client'),
)
然后我以技术经理身份登录并尝试使用此网址进行访问:
@permission_required(lambda u: u.has_perm('authentication.view_client'))
然后我收到错误/client/profile
。
我在名为function object is not iterable
的应用中创建了我的用户。 authentication
看起来像这样:
'
models,py
'
个人资料类有点大。请忽略它。现在我想要的是每次创建任何类型的不同用户时我都会分配权限。
如何解决错误以及如何实现此目的,以便一种类型的用户无法访问其他人的视图。输入网址?
在@python_2_unicode_compatible
class Profile(models.Model):
user = models.OneToOneField(User)
user_sex = (('MALE', 'Male'), ('FEMALE', 'Female'))
sex = models.CharField(max_length=6, default='Male', choices=user_sex)
address = models.CharField(max_length=250, null=True, blank=True)
city = models.CharField(max_length=250, null=True, blank=True)
state = models.CharField(max_length=250, null=True, blank=True)
country = models.CharField(max_length=250, null=True, blank=True)
phone = PhoneNumberField(blank=True)
zip = models.IntegerField(null=True, blank=True)
about = models.CharField(max_length=250, null=True, blank=True)
email_confirmed = models.BooleanField(default=False)
account_type = models.IntegerField(default=-1)
class Meta:
db_table = 'auth_profile'
class Employee(models.Model):
user = models.OneToOneField(User)
manager = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
designation = models.CharField(max_length=6)
class Meta:
db_table = 'auth_employee'
class Client(models.Model):
user = models.OneToOneField(User)
class Meta:
db_table = 'auth_client'
@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
if instance.profile.account_type == 0:
if not Client.objects.filter(user=instance).exists():
Client.objects.create(user=instance)
instance.client.save()
else:
instance.client.save()
if instance.profile.account_type == 1 or instance.profile.account_type == 2 or instance.profile.account_type == 3:
if not Employee.objects.filter(user=instance).exists():
Employee.objects.create(user=instance)
instance.employee.save()
else:
instance.employee.save()
以下是我的观点之一,客户可以更新其联系信息:
souldeux
我得到的错误:
@login_required(login_url='/login/')
@permission_required(lambda u: u.has_perm('authentication.view_client'))
def contact(request):
user = request.user
if request.method == 'POST':
# form = ContactForm()
form = ContactForm(request.POST)
if form.is_valid():
user.profile.address = form.cleaned_data.get('address')
user.profile.city = form.cleaned_data.get('city')
user.profile.state = form.cleaned_data.get('state')
user.profile.country = form.cleaned_data.get('country')
user.profile.phone = form.cleaned_data.get('phone')
user.profile.zip = form.cleaned_data.get('zip')
user.save()
messages.add_message(request,
messages.SUCCESS,
'Your contact was successfully edited.')
else:
form = ContactForm(instance=user, initial={
'address': user.profile.address,
'city': user.profile.city,
'state': user.profile.state,
'country': user.profile.country,
'phone': user.profile.phone,
'zip': user.profile.zip,
})
return render(request, 'client/client_contact.html', {'form': form})
答案 0 :(得分:0)
不是在permission_required
装饰器中传递lambda函数,而是将权限测试重新编写为独立函数,并通过适用于method_decorator
方法的dispatch
应用它: / p>
https://docs.djangoproject.com/en/dev/topics/class-based-views/intro/#decorating-the-class
How to use permission_required decorators on django class-based views
您还可以使用@user_passes_test
来装饰基于函数的视图。例如,您可能希望仅对与Client
对象关联的用户可见:
def user_has_client(user)
return hasattr(user, 'Client')
@user_passes_test(user_has_client, login_url='/')
def my_protected_view(request):
...
您也可以在测试中检查用户权限:https://docs.djangoproject.com/en/1.11/ref/contrib/auth/#django.contrib.auth.models.User.has_perm