Considere una aplicación simple de Django que contenga un modelo central llamado Project . Otros recursos de esta aplicación siempre están vinculados a un Project específico.
Código ejemplar:
class Project(models.Model): pass class Page(models.Model): project = models.ForeignKey(Project) Me gustaría aprovechar el sistema de permisos de Django para establecer permisos granulares por proyecto existente . En el caso del ejemplo, un usuario debería poder tener un permiso view_page para algunas instancias del proyecto y no tenerlo para otras.
Al final, me gustaría tener una función como has_perm que tome el nombre en clave del permiso y un proyecto como entrada y devuelva True si el usuario actual tiene el permiso en el proyecto dado.
¿Hay alguna manera de extender o reemplazar el sistema de autorización de Django para lograr algo como esto?
Podría extender el modelo de Group del usuario para incluir un enlace a Project y verificar tanto el proyecto del grupo como sus permisos. Pero eso no es elegante y no permite asignar permisos a usuarios individuales.
Algunas preguntas relacionadas en el foro de Django se pueden encontrar aquí:
Preguntas relacionadas con StackOverflow:
Mi respuesta se a user should be able to have a view_page permission for one project instance, and don't have it for another instance.
Entonces, básicamente, tendrá que capturar first user visit == first model instance , puede crear FirstVisit model que capturará y guardará cada primera instancia usando url , user.id y page.id , luego verificará si existe.
# model class Project(models.Model): pass class Page(models.Model): project = models.ForeignKey(Project) class FirstVisit(models.Model): url = models.URLField() user = models.ForeignKey(User) page = models.ForeignKey(Page) #views.py def my_view(request): if not FisrtVisit.objects.filter(user=request.user.id, url=request.path, page=request.page.id).exists(): # first time visit == first instance #your code... FisrtVisit(user=request.user, url=request.path, page=request.page.id).save()basado en esta solución
Sugiero usar la dirección Mac del dispositivo (computadora o teléfono inteligente) en lugar de la URL usando getmac para verificar la primera visita al máximo
Respuesta original: use django-guardian
Editar Como se discutió en los comentarios, creo que django-guardian ofrece la forma más fácil y limpia de lograr esto. Sin embargo, otra solución es crear un usuario personalizado.
has_perm en su nuevo modelo de usuario. from django.db import models from my_app import Project class CustomUser(...) projects = models.ManyToManyField(Project) def has_perm(self, perm, obj=None): if isinstance(obj, Project): if not obj in self.projects.objects.all(): return False return super().has_perm(perm, obj)