Models in 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)
I need to select from DB this data:
NAME (from record)
and fields related with this record
[NAME (from key), VALUE (from value)]
[NAME (from key), VALUE (from value)]
[...]
May I use django ORM to make this selection? (for example in SQL select looks like this)
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
Join Queries Join can be done with select_related method: Django defines this function as Returns a QuerySet that will “follow” foreign-key relationships, selecting additional related-object data when it executes its query.
select_related() “follows” foreign-key relationships, selecting additional related-object data when it executes its query. prefetch_related() does a separate lookup for each relationship and does the “joining” in Python.
You can also use the chain() method from the Itertools module, which allows you to combine two or more QuerySets from different models through concatenation. Alternatively, you can use union() to combine two or more QuerySets from different models, passing all=TRUE if you want to allow duplicates.
The following selects the values related to particular record id. You can then follow the foreign keys to get the related record and key. Using select_related
minimises database lookups.
# 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 %}
In your sql, you had WHERE record_id = 1
, so I showed how to get all the values for a particular record. You could also select the values for more that one record in one query.
# 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')
Should be relatively straightforward, since you already have the foreign keys tied together.
Record.objects.select_related().filter(id = variable_that_stores_id)
You can combine that with only to limit the fields that you want to bring back.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With