简体   繁体   中英

How use get_queryset in Django Admin for retrieve only objects created by AdminUser?

I have an app with 3 kind of users:

  • RegularUsers: Users of the app. Can't login admin site. They are managed by AdminUsers. They are the final users of the app.
  • AdminUsers: They can login admin site in order to manage their RegularUsers. They just can manage users created by themselves.
  • SuperUser. The admin of the WebApp having all permissions.

I have different Models too. The website is a webGallery. Above you have my

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)

...

In get_queryset, I don't know how to access Admin User in order to compare it with request.user. My final purpose is that users can only see the content created by their admin user, that is, by the user who created the album.

Can you use Djangos LogEntry ? This will work only when objects are created via the Admin. If not you'll have to add a user field to Album to store who created it.

For example:

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)

A similar approach can be taken with ImagenAdmin.

I suppose you could also hijack django.contrib.admin.models.LogEntryManager to log an addition when done by some other means (views.py etc).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM