如何在Django Admin中使用get_queryset仅检索AdminUser创建的对象?

时间:2018-11-09 16:55:34

标签: python django django-admin django-queryset django-users

我有一个拥有3种用户的应用程序:

  • RegularUsers:应用程序的用户。无法登录管理站点。它们由AdminUsers管理。他们是该应用程序的最终用户。
  • AdminUsers:他们可以登录管理站点以便管理其RegularUsers。他们只是可以管理自己创建的用户。
  • 超级用户。具有所有权限的WebApp的管理员。

我也有不同的型号。该网站是一个网络画廊。上方有我的

MODELS.PY

class MyUser(AbstractUser):
    descripcion = models.TextField(blank=True)
    telefono = PhoneNumberField()
    avatar = models.ImageField(verbose_name='Imagen de perfil',
                               upload_to='img/avatars',
                               default='img/placeholder-image.png')
    def __str(self):
        return self.username

class RegularUser(MyUser):
    MyUser.is_staff = False
    MyUser.is_superuser = False

    class Meta:
        verbose_name = 'Usuario Regular'
        verbose_name_plural = 'Usuarios Regulares'

class AdminUser(MyUser):
    usuarios = models.ManyToManyField(RegularUser,    help_text="Selecciona los usuarios que administra", blank=True)

    class Meta:
        verbose_name = 'Administrador'
        verbose_name_plural = 'Administradores'

class Album(models.Model):
    id_album = models.AutoField(primary_key=True)
    titulo = models.CharField(max_length=40, null=False)
    ...
    usuario = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    ....
    # admin = models.ForeignKey(Familiar, on_delete=models.CASCADE, related_name="Administrador") ??¿¿
    evento = models.ForeignKey(Evento, on_delete=models.CASCADE, blank=True, null=True)

class Multimedia(models.Model):
    titulo = models.CharField(max_length=80)
    album = models.ForeignKey(Album, on_delete=models.CASCADE)
    keyword = models.ManyToManyField('Keyword', help_text="Selecciona las palabras clave para etiquetar.")
    ......


class Imagen(Multimedia):
    titulo = models.CharField(max_length=100)
    image_width = models.PositiveSmallIntegerField(default=640)
    image_height = models.PositiveSmallIntegerField(default=480)
    fichero_imagen = models.ImageField(verbose_name='Archivo de imagen',
                                       upload_to='files/img',
                                       width_field='image_width',
                                       height_field='image_height')
    thumbnail = ImageSpecField(source='fichero_imagen',
                               processors=[ResizeToFill(600, 300)],
                               format='JPEG',
                               options={'quality': 60})

    def filename(self):
        return os.path.basename(self.fichero_imagen.name)

ADMIN.PY

....
@admin.register(Album)
class AlbumAdmin(admin.ModelAdmin):
    fields = ['titulo', 'descripcion', 'thumbnail', 'evento', 'usuario']
    date_hierarchy = 'fecha_creacion'
    list_filter = ('fecha_creacion', 'usuario')
    inlines = [ImagenInstanceInline]

    # def get_queryset(self, request):
    #     qs = super(AlbumAdmin, self).get_queryset(request)
    #     if request.user.is_superuser:
    #         return qs
    #     return qs.filter( = request.user)

@admin.register(Imagen)
class ImagenAdmin(admin.ModelAdmin):
    list_display = ('preview', 'titulo',)
    exclude = ('path',)
    #fields = ('image_tag',)
    readonly_fields = ('vista_previa',)

    def vista_previa(self, obj):
        return mark_safe('<img style="border-radius:25px;" src="{url}" width="{width}" heigth={heigth} />'.format(
            url=obj.fichero_imagen.url,
            width=300,
            heigth=300,
        )
        )
    def preview(self, obj):
        return mark_safe('<img style="border-radius:25px;" src="{url}" width="{width}" heigth={heigth} />'.format(
            url=obj.fichero_imagen.url,
            width=100,
            heigth=100,
        )
        )
    # def get_queryset(self, request):
    #     qs = super(ImagenAdmin, self).get_queryset(request)
    #     if request.user.is_superuser:
    #         return qs
    #     return qs.filter(author = request.user)

...

在get_queryset中,我不知道如何访问Admin User以便将它与request.user进行比较。我的最终目的是,用户只能看到其管理员用户(即创建相册的用户)创建的内容。

1 个答案:

答案 0 :(得分:0)

您可以使用Django LogEntry吗?仅当通过管理员创建对象时,此方法才有效。如果不是,则必须向“相册”中添加用户字段以存储创建它的人。

例如:

from django.contrib.admin.models import LogEntry, ADDITION
from django.contrib.contenttypes.models import ContentType

@admin.register(Album)
class AlbumAdmin(admin.ModelAdmin):

    ...

    def get_queryset(self, request):
        qs = super(AlbumAdmin, self).get_queryset(request)
        if request.user.is_superuser:
            return qs

        album_ct = ContentType.objects.get_for_model(Album)
        log_entries = LogEntry.objects.filter(
            content_type=album_ct, 
            user=request.user,
            action_flag=ADDITION
        )
        user_album_ids = [a.object_id for a in log_entries]
        return qs.filter(id__in=user_album_ids)

ImagenAdmin可以采用类似的方法。

我想您还可以劫持django.contrib.admin.models.LogEntryManager以通过其他方式(views.py等)完成日志记录。