Code

Ticket #5937: django-generic-relation-query.patch

File django-generic-relation-query.patch, 2.4 KB (added by Joshua 'jag' Ginsberg <jag@…>, 6 years ago)
  • django/db/models/query.py

     
    960960    current_column = column 
    961961    intermediate_table = None 
    962962    join_required = False 
     963    generic_relation_required = False 
    963964 
    964965    name = path.pop(0) 
    965966    # Has the primary key been requested? If so, expand it out 
     
    980981            # This process hijacks current_table/column to point to the 
    981982            # intermediate table. 
    982983            current_table = "m2m_" + new_table 
    983             intermediate_table = field.m2m_db_table() 
    984984            join_column = field.m2m_reverse_name() 
    985             intermediate_column = field.m2m_column_name() 
    986  
     985            from django.contrib.contenttypes.generic import GenericRelation 
     986            if not isinstance(field, GenericRelation): 
     987                intermediate_table = field.m2m_db_table() 
     988                intermediate_column = field.m2m_column_name() 
     989            else: 
     990                generic_relation_required = True 
     991                from django.contrib.contenttypes.models import ContentType 
     992                ct_obj = ContentType.objects.get( 
     993                    app_label=current_opts.app_label, 
     994                    model=current_opts.object_name.lower() 
     995                ) 
    987996            raise FieldFound 
    988997 
    989998        # Does the name belong to a reverse defined many-to-many field? 
     
    10601069            # for the search. No need to join an extra table just 
    10611070            # to check the primary key. 
    10621071            new_table = current_table 
     1072        elif generic_relation_required: 
     1073            ct_field = new_opts.get_field(field.content_type_field_name) 
     1074            pk_field = new_opts.get_field(field.object_id_field_name) 
     1075            joins[qn(new_table)] = ( 
     1076                qn(new_opts.db_table), "INNER JOIN", 
     1077                "%s.%s = %s.%s" % (qn(table), qn(current_opts.pk.column), qn(new_table), qn(pk_field.column)) 
     1078            ) 
     1079            where.append(get_where_clause('exact', qn(new_table) + '.', 
     1080                         ct_field.column, ct_obj.id, ct_field.db_type())) 
     1081            params.extend(field.get_db_prep_lookup('exact', ct_obj.id)) 
     1082            join_column = None 
    10631083        else: 
    10641084            # There are 1 or more name queries pending, and we have ruled out 
    10651085            # any shortcuts; therefore, a join is required.