Как запросить разницу в данных из функции __unicode__() в Django

#django #orm

Вопрос:

У меня была модель:

 class Menu(models.Model):
     menu_id=models.CharField(max_length=30)
     name_vi=models.CharField(max_length=80)
     name_en=models.CharField(max_length=80)

     def get_all_menu(self):
          return Menu.objects.all()

     def __unicode__(self):
          return self.name_vi

     class Admin:pass
 

при вызове get_all_menu я хочу, чтобы он возвращал 2d массив модели меню, включающей 3 поля: menu_id, menu_vi, menu_en. Но он возвращает только name_vi, то же самое, что и функция unicode.

Могу ли я запросить полные 3 поля в этой ситуации?

Ответ №1:

Во-первых, метод get_all_menu должен быть методом менеджера моделей, а не методом модели, как у вас, поскольку это функция, которая действует на всю таблицу, а не на одну строку/экземпляр:

 class MenuManager(models.Manager):
    def get_all_menu(self):
      return self.objects.all()

class Menu(models.Model):
    objects = MenuManager()
 

Таким образом, теперь вы можете использовать это, чтобы получить все строки таблицы:

 Menu.objects.get_all_menu()
 

Во-вторых, функция unicode не имеет ничего общего с запросами. Это просто функция, помогающая отображать чувствительное имя объекта при его печати.

В-третьих, почему вы хотите, чтобы при запросе базы данных возвращался 2d — массив? При выполнении запроса вы получаете обратно 3 объекта, поэтому у вас есть ссылка на все их атрибуты/столбцы:

 menus = Menu.objects.get_all_menus()
for menu in menus:
    print menu.menu_id
    print menu.name_vi
    print menu.name_en
 

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

1. Похоже, нет никакого смысла вкладывать get_all_menu в Менеджера, так как это идентично методу менеджера all() . Я подозреваю (хотя , конечно, ОП нам не говорит), что он/она хочет использовать это в администраторе list_display и, конечно, просто видит представление юникода.

2. Согласен, я просто указывал на разницу между работой на уровне строк, а не на уровне таблиц.

3. Отлично! Я понял! Большое спасибо.