简体   繁体   English

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

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

I have an app with 3 kind of users: 我有3种类型的用户的应用程序:

  • RegularUsers: Users of the app. RegularUsers:应用程序的用户。 Can't login admin site. 无法登录管理站点。 They are managed by AdminUsers. 它们由AdminUsers管理。 They are the final users of the app. 他们是该应用程序的最终用户。
  • AdminUsers: They can login admin site in order to manage their RegularUsers. AdminUsers:他们可以登录管理站点以管理其RegularUsers。 They just can manage users created by themselves. 他们只是可以管理自己创建的用户。
  • SuperUser. 超级用户。 The admin of the WebApp having all permissions. 具有所有权限的WebApp的管理员。

I have different Models too. 我也有不同的型号。 The website is a webGallery. 该网站是一个网络画廊。 Above you have my 上面有我的

MODELS.PY 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.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. 在get_queryset中,我不知道如何访问Admin User以便将它与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 ? 可以使用Django的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. 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). 我想您还可以劫持django.contrib.admin.models.LogEntryManager以通过其他方式(views.py等)完成日志记录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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