I have a problem. I already have two solution for my problem, but i was wondering which of those is the faster solution. I guess that the second solution is not only more convienient- to use but also faster, but i want to be sure, so thats the reason why im asking. My problem is i want to group multiple rows together. The group won't hold any meta data. So im only interested in runtime.
On the one hand i can use a Integer field and filter it later on when i need to get all entries that belong to the group. I guess runtime of O(n).
class SingleEntries(models.Model):
name = models.CharField(max_length=20)
group = models.IntegerField(null=True)
def find_all_group_members(id):
return SingleEntries.objects.filter(group=id)
The second solution and probably the more practicle way would be to create a foreign key to another model only using the pk there. Then i can use the reverse relation to find all the entries that belong to the group.
class Group(models.Model):
id = models.AutoField(primary_key=True)
class SingleEntries(models.Model):
name = models.CharField(max_length=20)
group = models.ForeignKey(Group,on_delete=models.CASCADE,null=True)
def find_all_group_members(id):
return Group.objects.get(id=id).singleentries_set.all()
The first is more efficient, since this will use one query, whereas the latter will first fetch the Group
, and then another one for the SingleEntries
.
Indeed, if you work with:
SingleEntries.objects.filter(group=id)
this will make a simple query:
SELECT appname_singleentries.* FROM appname_singleentries WHERE appname_singleentries.group_id = id
It thus does not first fetch the Group
into memory.
The latter will however make two queries. Indeed, it will first make a query to retrieve the Group
, and then it will make a query like the one above to fetch the SingleEntries
.
The two are also semantically not entirely the same: if there is no such group, then the former will return an empty QuerySet
, whereas the latter will raise a Group.DoesNotExists
exception.
But you can model this with:
class Group(models.Model):
pass
class SingleEntries(models.Model):
name = models.CharField(max_length=20)
group = models.ForeignKey(Group,on_delete=models.CASCADE,null=True)
def find_all_group_members(id):
return SingleEntries.objects.filter(group_id=id)
So you can use a Group
model without having to retrieve the Group
first.