2011-10-26 7 views
8

ERRDjango ORM wybierz Z dołączyć

modele w Django:

class Key(models.Model): 
    id  = models.AutoField(primary_key=True, blank=True) 
    name = models.CharField(max_length=50) 


class Record(models.Model): 
    id   = models.AutoField(primary_key=True, blank=True) 
    project_id = models.IntegerField() 
    name  = models.CharField(max_length=50) 


class Value(models.Model): 
    id  = models.AutoField(primary_key=True, blank=True) 
    record = models.ForeignKey(Record) 
    key  = models.ForeignKey(Key) 
    value  = models.CharField(max_length=255) 

muszę wybrać z DB te dane:

NAME (from record) 
and fields related with this record 
[NAME (from key), VALUE (from value)] 
[NAME (from key), VALUE (from value)] 
[...] 

mogę użyć Django ORM, aby ten wybór? (na przykład w przypadku wyboru SQL wygląda tak)

SELECT 
    `keeper_record`.`id` AS `record_id`, 
    `keeper_record`.`name` AS `name`, 
    `keeper_record`.`desc` AS `desc`, 
    `keeper_key`.`name` AS `key_name`, 
    `keeper_key`.`desc` AS `key_desc`, 
    `keeper_value`.`value` AS `value_value` 
FROM `keeper_record` 
JOIN `keeper_value` ON `keeper_record`.`id` = `keeper_value`.`record_id` 
JOIN `keeper_key` ON `keeper_key`.`id` = `keeper_value`.`key_id` 
WHERE record_id = id 

Odpowiedz

7

Poniższa tabela zawiera wartości związane z określonym identyfikatorem rekordu. Następnie możesz postępować zgodnie z kluczami obcymi, aby uzyskać powiązany rekord i klucz. Korzystanie z select_related minimalizuje wyszukiwanie bazy danych.

# Select all values related to a record in your view 
record = Record.objects.get(pk=record_id) 
values = Value.objects.filter(record=record).select_related() 

# In your template 
{% for value in values %} 
{{ value.record.name }} - {{ value.key.name }} - {{ value.value }} 
{% endfor %} 

Wybór więcej niż jeden rekord

w twojej sql, miałeś WHERE record_id = 1, więc pokazałem, jak uzyskać wszystkie wartości dla danego rekordu. Możesz także wybrać wartości dla więcej niż jednego rekordu w jednym zapytaniu.

# filter all records which belong to the project with `project_id=1` 
records = Record.objects.filter(project_id=1) 
# select all values that belong to these records 
values = Value.objects.filter(record__in=records).select_related().order_by('record') 
+0

Słusznie zrozumiałem, że dla każdego rekordu potrzebne jest jedno dodatkowe zapytanie, aby wybrać wartości, a jeśli chcę wybrać wszystkie (lub kilka) rekordów, potrzebuję wybranych wartości w pętli? – Deadly

+2

Zaktualizowałem odpowiedź na wybór więcej niż jednego rekordu. Mam nadzieję, że to pomoże. – Alasdair

+0

Tak, naprawdę pomogło mi zrozumieć ORM Django, dziękuję. – Deadly

2

Powinny być stosunkowo proste, ponieważ masz już powiązane klucze obce.

Record.objects.select_related().filter(id = variable_that_stores_id) 

Można połączyć to z only do ograniczenia pola, które chcesz przywrócić.

+0

Funkcja 'select_related' nie będzie tutaj działała, ponieważ nie podąża za kluczem obcym" do tyłu ". – Alasdair

+0

Rozumiem. Wygląda na to, że pytanie zmieniło się nieco od czasu mojego posta, ale niezależnie od tego było ono niepoprawne lub niekompletne. – Jordan