Jak uzyskać zestaw QuerySet wszystkich wierszy, z określonymi polami dla każdego z nich?

109

Mam model Employeesi chciałbym mieć zestaw QuerySet zawierający wszystkie wiersze, ale z określonymi polami z każdego wiersza, a nie ze wszystkimi polami.

Wiem, jak sprawdzać wszystkie wiersze z tabeli / modelu:

Employees.objects.all()

Chciałbym wiedzieć, jak wybrać pola dla każdego elementu Queryset. Jak mogę to zrobić?

zentenk
źródło
Co masz na myśli mówiąc „i używając tylko jednego”? A SELECT colzamiast SELECT *?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

193
Employees.objects.values_list('eng_name', flat=True)

To tworzy płaską listę wszystkich eng_names. Jeśli chcesz mieć więcej niż jedno pole w wierszu, nie możesz utworzyć płaskiej listy: spowoduje to utworzenie listy krotek:

Employees.objects.values_list('eng_name', 'rank')
Daniel Roseman
źródło
dzięki za odpowiedź, a co jeśli chcę zaznaczyć tylko 1 lub więcej pól (nie wszystkie)?
zentenk
Przepraszam, nie rozumiem pytania.
Daniel Roseman,
4
udostępnij dokument. to pomoże innym
bob marti
26

Oprócz tego, values_listjak Daniel wspomina , możesz również użyć only(lub deferdla odwrotnego efektu), aby uzyskać zestaw zapytań obiektów mających tylko swój identyfikator i określone pola:

Employees.objects.only('eng_name')

Spowoduje to uruchomienie pojedynczego zapytania:

SELECT id, eng_name FROM employees
Oskar Persson
źródło
3
To polecenie zwraca mi wszystkie pola dla mojego Django w wersji 2.1.3 i Pythona w wersji 3.6.2.
Ananthi
Pobierze tylko to pole, ale jeśli spróbujesz uzyskać dostęp do innych pól, zostanie wykonane oddzielne zapytanie do bazy danych. Jest to więc dobra technika optymalizacji, ale upewnij się, że nie tworzysz tych dodatkowych zapytań. W przeciwnym razie stracisz wydajność zamiast ją zyskać.
Eerik Sven Puudist
6

Możemy wybrać wymagane pola nad wartościami.

Employee.objects.all().values('eng_name','rank')
Alok Choudhary
źródło
Po pomyślnym uruchomieniu zapytania, jak zapisać wartość pola w zmiennej, np. var_name = <query_name>. <field_name> ?
user12379095
@ user12379095, po prostu tak:var_name = Employee.objects.all().values('eng_name','rank')
theQuestionMan,
@ user12379095, a następnie użyj tej zmiennej nazwa_zmiennej - na przykład: wypisz wszystkie nazwiska i rangę pracowników, możesz to zrobić:for person in var_name: print(person['eng_name'] + " " + person['rank'])
theQuestionMan
3

Odpowiedź Oskara Perssona jest najlepszym sposobem na poradzenie sobie z tym, ponieważ ułatwia przekazywanie danych do kontekstu i normalne traktowanie ich z szablonu, gdy otrzymujemy instancje obiektów (łatwo iterowalne w celu uzyskania właściwości) zamiast zwykłej listy wartości.

Następnie możesz łatwo zdobyć poszukiwany rekwizyt:

for employee in employees:
    print(employee.eng_name)

Lub w szablonie:

{% for employee in employees %}

    <p>{{ employee.eng_name }}</p>

{% endfor %}
PeteMaikel
źródło
2

Możesz użyć value_list obok filtra w ten sposób;

active_emps_first_name = Employees.objects.filter(active=True).values_list('first_name',flat=True)

Więcej szczegółów tutaj

7guyo
źródło
0

Odpowiedź Daniela jest na miejscu. Jeśli chcesz zapytać o więcej niż jedno pole, wykonaj następujące czynności:

Employee.objects.values_list('eng_name','rank')

Spowoduje to wyświetlenie listy krotek. Nie możesz użyć named = Ture podczas odpytywania więcej niż jednego pola.

Co więcej, jeśli wiesz, że istnieje tylko jedno pole z tą informacją i znasz identyfikator pk, zrób to:

Employee.objects.values_list('eng_name','rank').get(pk=1)
Sumit Vaise
źródło