这是一个基本的api,我有3种用户 - >管理员,公司,员工。
管理员可以查看,编辑和删除所有这些,公司可以查看和删除员工,员工只能看到他公司更新的视频。
因此,每个公司都会有一个管理面板,他们可以上传培训视频并注册其员工,因此每个公司都有自己的面板,他们没有看到其他公司。
我是否需要创建自定义用户模型才能执行此操作?我该如何创建该模型,如何设置这些权限?
如何管理公司和员工可以访问或不能访问的注册表单,登录名,网址
my models.py:
from django.db import models
from django.utils import timezone
# Create your models here.
class Company(models.Model):
user = models.ForeignKey('auth.User', on_delete=models.DO_NOTHING)
empresa_nome = models.CharField(max_length=100, default='')
razao_social = models.CharField(max_length=100, default='')
cnpj = models.CharField(max_length=18, default='')
def __str__(self):
return self.empresa_nome
class Employee(models.Model):
empresa = models.ForeignKey(Company, on_delete=models.DO_NOTHING, related_name='employees')
user = models.ForeignKey('auth.User', on_delete=models.DO_NOTHING)
phone = models.CharField(max_length=20)
def __str__(self):
return self.phone
class Test(models.Model):
company = models.ForeignKey(Company, on_delete=models.DO_NOTHING, related_name='treinamentos')
user = models.ForeignKey('auth.User', on_delete=models.DO_NOTHING)
categoria = models.CharField(max_length=100)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.categoria
class Video(models.Model):
video = models.ForeignKey(Test, on_delete=models.DO_NOTHING, related_name='video')
user = models.ForeignKey('auth.User', on_delete=models.DO_NOTHING)
url = models.CharField(max_length=150)
ordem = models.IntegerField(null=False)
pergunta = models.CharField(max_length=250)
certo = models.CharField(max_length=250)
errado = models.CharField(max_length=250)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.categoria
serializers.py:
from django.contrib.auth.models import User
from rest_framework import serializers
from .models import Company, Employee, Test, Video
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email', 'is_staff')
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
exclude = []
class VideoSerializer(serializers.ModelSerializer):
class Meta:
model = Video
exclude = []
class TestSerializer(serializers.ModelSerializer):
video = VideoSerializer(read_only=True, many=True)
class Meta:
model = Test
fields = ('id', 'categoria', 'video', 'created_at', 'updated_at')
exclude = []
class CompanySerializer(serializers.ModelSerializer):
employees = EmployeeSerializer(read_only=True, many=True)
treinamentos = TestSerializer(read_only=True, many=True)
#user_obj = UserSerializer(read_only=True)
class Meta:
model = Company
fields = ('id', 'empresa_nome', 'razao_social', 'cnpj', 'employees', 'treinamentos')
exclude = []
urls.py
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework import routers, viewsets
from restcompanies.views import UserViewSet, CompanyViewSet, EmployeeViewSet, TestViewSet, VideoViewSet
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'companies', CompanyViewSet)
router.register(r'employees', EmployeeViewSet)
router.register(r'tests', TestViewSet)
router.register(r'videos', VideoViewSet)
app_name = 'restcompanies'
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls', namespace='restcompanies')),
]
答案 0 :(得分:1)
您可以通过检查模板中的权限并根据权限分支渲染来修改视图。例如,您可以设置" can_edit"标记并在上下文中传回。然后在你的模板中执行:
{% if can_edit %}
*edit only code goes here
{% endif %}
或者,您可以根据角色和公司为同一视图提供不同的模板。这可以通过使用TemplateView并覆盖get_template_names来实现,例如
class AdminView(TemplateView):
def get_template_names(self):
if empresa_nome == 'company1':
return 'company1template.html'
但在我看来,后一种解决方案只有在模板完全不同的情况下才有用,而如果它只是在类似的模板中启用/禁用选项,那么第一种解决方案就更好了。
您不一定需要自定义用户模型,因为默认情况下您可以在django中创建许多不同的角色并将其分配给用户。例如,在一个项目中,我使用用户角色检查权限:
def checkPermissions(request):
if not request.user.is_authenticated():
return None
if request.user.groups.filter(name='MerchantSuperAdmin').exists() or request.user.is_superuser:
return 'SU' #can access whatever
if request.user.groups.count() == 1 and request.user.groups.filter(name='employee').exists():
return 'readonly'
在这种情况下,我有一个名为MerchantSuperAdmin的自定义用户角色和另一个名为Employee的用户角色,我将这些角色分配给不同的用户。
...等。然后在模板中,您可以根据上下文['权限']或类似内容选择javascript的html。
答案 1 :(得分:0)
在django中,权限是基于模型/类,而不是基于实例/对象。如果你希望它们是基于对象的,你将不得不编写自己的权限模型或(我建议这样做)使用一个现有的包来做这件事。我喜欢的包是django-guardian(https://django-guardian.readthedocs.io/en/stable/),它有非常好的文档并且非常易于使用。此外,由于您正在使用django rest框架,因此很可能已安装它,因为django rest将其列为其安装说明中的可选软件包之一。
答案 2 :(得分:0)
由于您希望将用户与公司相关联并对其应用权限逻辑,是的,可能使用自定义用户模型是最佳选择。您可以阅读有关如何执行此操作in the Django docs。
Django Rest Framework允许您根据任意条件允许/禁止访问视图,包括所请求的资源。请参阅documentation section about custom permissions。
答案 3 :(得分:0)
我会使用带继承的自定义权限。
http://www.django-rest-framework.org/api-guide/permissions/#custom-permissions
class IsAdmin(permissions.BasePermission):
def has_permission(self, request, view):
return do_some_custom_checking(...)
class IsCompany(IsAdmin):
def has_permission(self, request, view):
return do_some_custom_checking(...) or super(IsCompany, self).has_permission(request, view)
class IsEmployee(IsCompany):
def has_permission(self, request view):
return do_some_custom_checking(....) or super(IsEmployee, self).has_permission(request, view)