Creating efficient database queries for hierarchical models (django)

后端 未结 3 1768
我在风中等你
我在风中等你 2021-02-06 12:07

Consider this (django) model:

class Source(models.Model):
   # Some other fields
   type = models.ForeignKey(\'Type\')

class Type(models.Model):
    # Some othe         


        
3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-06 12:13

    How do I efficiently query so that if I select Source by Type, I also retrieve Sources which have a Type that is a child of the given type?

    For the example given, it is fairly easy to setup a query because no recursive calls need to be made, and your "hierarchy" is only one level deep:

    class Source(models.Model):
       # Some other fields
       type = models.ForeignKey('Type')
    
    class Type(models.Model):
        # Some other fields
        name = models.CharField(max_length=100)
        parent = models.ForeignKey('self', blank=True, null=True)
    
    #We want all sources under in the type = Radio tree
    type = Type.objects.get(name='Radio')
    qs = Source.objects.filter(type__parent=type)
    
    #We want all sources that are `Forum` typed
    type = Type.objects.get(name='Forum')
    qs = Source.objects.filter(type=type)
    

    This is assuming that Source is always related to a "child" type and not to the "parent."

    If sources can also be related to the "parent" types, you can use Q for complex queries:

    >>> from django.db.models import Q
    >>> type = Type.objects.get(name='Radio')
    >>> qs = Source.objects.filter(Q(type=type)|Q(type_parent=type))
    >>> #if Radio type id = 2
    >>> print qs.query
    SELECT `app_source`.`id`, `app_source`.`type_id` FROM `app_source` INNER JOIN `app_type` ON  (`app_source`.`type_id` = `app_type`.`id`) WHERE (`app_source`.`type_id` = 2  OR `app_type`.`parent_id` = 2 )
    >>> 
    

    If you have a truly hierarchical trees in your tables, this method is much less usable, and you should seek out another solution.

提交回复
热议问题