Как использовать get_queryset в Django Admin для получения только объектов, созданных AdminUser? - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть приложение с 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 голосов
/ 09 ноября 2018

Можете ли вы использовать Djangos 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 и т. Д.).

...