есть ли эффективный способ использовать поле связанной модели в list_display?

#django #python-3.x #django-models #django-admin

#django #python-3.x #django-модели #django-администратор

Вопрос:

у меня есть две модели — модель пользователя (встроенная в django) и другая модель, называемая usertypes, в которой в качестве внешнего ключа используется user. Я сделал модель usertypes встроенной в модель пользователя. В модели usertypes есть поле с именем staff_status, я хочу использовать это поле (staff_status) в list_display. Я нашел решение этой проблемы с помощью callable, но я также прочитал, что использование callable func замедляет процесс, потому что он много раз обращается к базе данных, а затем я прочитал, что использование get_queryset может решить проблему, но я не знаю, как использовать query_set для решения этой проблемы или есть другой более эффективный способ решить эту проблему.

 class UserTypesInline(admin.TabularInline):
    model = UserTypes
    raw_id_fields = ['user']

class UserAdmin(BaseUserAdmin):
    inlines = [UserTypesInline]
    list_display = ('username','staff',)

    def staff(self, instance):
      return instance.usertypes.staff_status

    # def get_queryset(self,request):
    #     qs = super(UserAdmin, self).get_queryset(request)
    #     a = qs.select_related('usertypes')
    #     return a



admin.site.unregister(User)
admin.site.register(User, UserAdmin)
  
 class UserTypes(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    staff_choices = (
        ('', ''),
        ('Admin', 'Admin'),
        ('Chef', 'Chef'),
        ('Delivery Boy', 'Delivery Boy'),
    )
    staff_status = models.CharField(max_length=15, choices=staff_choices, default=staff_choices[0][0]) 

    def __str__(self):
        return self.staff_status
  

Ответ №1:

Вам нужно установить list_select_related атрибут, чтобы указать Django выбирать связанные элементы вместе с исходным набором запросов списка.

 class UserAdmin(BaseUserAdmin):
    inlines = [UserTypesInline]
    list_display = ('username','staff',)
    list_select_related = ('usertypes',)

    def staff(self, instance):
      return instance.usertypes.staff_status
  

(Я думаю, что ваш закомментированный код сработал бы, хотя — что произошло, когда вы попробовали это?)

Комментарии:

1. прокомментированный код показывает это (<QuerySet [<User: cheff>, <User: sohail>, <User: superadmin>]> ) это показывает только имена пользователей, но мне нужен staff_status, который находится в модели usertypes

2. Я удаляю обе функции get_queryset и def staff и использую этот код list_select_related = (‘usertypes’,) list_display = [‘username’, ‘usertypes’] этот способ правильный или он выполняет то же количество обращений к базе данных, что и функция def staff?