示例#1
0
 def _get_mm_case_path_info(self, direct=False):
     pathinfos = []
     linkfield1 = _get_field(self.through, 'content_object')
     linkfield2 = _get_field(self.through, self.m2m_reverse_field_name())
     if direct:
         join1infos = linkfield1.get_reverse_path_info()
         join2infos = linkfield2.get_path_info()
     else:
         join1infos = linkfield2.get_reverse_path_info()
         join2infos = linkfield1.get_path_info()
     pathinfos.extend(join1infos)
     pathinfos.extend(join2infos)
     return pathinfos
示例#2
0
 def _get_mm_case_path_info(self, direct=False):
     pathinfos = []
     linkfield1 = _get_field(self.through, 'content_object')
     linkfield2 = _get_field(self.through, self.m2m_reverse_field_name())
     if direct:
         join1infos = linkfield1.get_reverse_path_info()
         join2infos = linkfield2.get_path_info()
     else:
         join1infos = linkfield2.get_reverse_path_info()
         join2infos = linkfield1.get_path_info()
     pathinfos.extend(join1infos)
     pathinfos.extend(join2infos)
     return pathinfos
示例#3
0
 def _get_gfk_case_path_info(self, direct=False):
     pathinfos = []
     from_field = self.model._meta.pk
     opts = self.through._meta
     object_id_field = _get_field(self.through, 'object_id')
     linkfield = _get_field(self.through, self.m2m_reverse_field_name())
     if direct:
         join1infos = [PathInfo(self.model._meta, opts, [from_field], self.rel, True, False)]
         join2infos = linkfield.get_path_info()
     else:
         join1infos = linkfield.get_reverse_path_info()
         join2infos = [PathInfo(opts, self.model._meta, [object_id_field], self, True, False)]
     pathinfos.extend(join1infos)
     pathinfos.extend(join2infos)
     return pathinfos
示例#4
0
 def _get_gfk_case_path_info(self, direct=False):
     pathinfos = []
     from_field = self.model._meta.pk
     opts = self.through._meta
     object_id_field = _get_field(self.through, 'object_id')
     linkfield = _get_field(self.through, self.m2m_reverse_field_name())
     if direct:
         join1infos = [PathInfo(self.model._meta, opts, [from_field], self.rel, True, False)]
         join2infos = linkfield.get_path_info()
     else:
         join1infos = linkfield.get_reverse_path_info()
         join2infos = [PathInfo(opts, self.model._meta, [object_id_field], self, True, False)]
     pathinfos.extend(join1infos)
     pathinfos.extend(join2infos)
     return pathinfos
示例#5
0
 def get_extra_restriction(self, where_class, alias, related_alias):
     extra_col = _get_field(self.through, 'content_type').column
     content_type_ids = [
         ContentType.objects.get_for_model(subclass).pk
         for subclass in _get_subclasses(self.model)
     ]
     return ExtraJoinRestriction(related_alias, extra_col, content_type_ids)
示例#6
0
    def similar_objects(self):
        lookup_kwargs = self._lookup_kwargs()
        lookup_keys = sorted(lookup_kwargs)
        qs = self.through.objects.values(*six.iterkeys(lookup_kwargs))
        qs = qs.annotate(n=models.Count("pk"))
        qs = qs.exclude(**lookup_kwargs)
        qs = qs.filter(tag__in=self.all())
        qs = qs.order_by("-n")

        # TODO: This all feels like a bit of a hack.
        items = {}
        if len(lookup_keys) == 1:
            # Can we do this without a second query by using a select_related()
            # somehow?
            f = _get_field(self.through, lookup_keys[0])
            objs = f.rel.to._default_manager.filter(**{"%s__in" % f.rel.field_name: [r["content_object"] for r in qs]})
            for obj in objs:
                items[(getattr(obj, f.rel.field_name),)] = obj
        else:
            preload = {}
            for result in qs:
                preload.setdefault(result["content_type"], set())
                preload[result["content_type"]].add(result["object_id"])

            for ct, obj_ids in preload.items():
                ct = ContentType.objects.get_for_id(ct)
                for obj in ct.model_class()._default_manager.filter(pk__in=obj_ids):
                    items[(ct.pk, obj.pk)] = obj

        results = []
        for result in qs:
            obj = items[tuple(result[k] for k in lookup_keys)]
            obj.similar_tags = result["n"]
            results.append(obj)
        return results
示例#7
0
def _get_subclasses(model):
    subclasses = [model]
    if VERSION < (1, 8):
        all_fields = (_get_field(model, f) for f in model._meta.get_all_field_names())
    else:
        all_fields = model._meta.get_fields()
    for field in all_fields:
        # Django 1.8 +
        if not RelatedObject and isinstance(field, OneToOneRel) and getattr(field.field.rel, "parent_link", None):
            subclasses.extend(_get_subclasses(field.related_model))

        # < Django 1.8
        if RelatedObject and isinstance(field, RelatedObject) and getattr(field.field.rel, "parent_link", None):
            subclasses.extend(_get_subclasses(field.model))
    return subclasses
示例#8
0
def _get_subclasses(model):
    subclasses = [model]
    if VERSION < (1, 8):
        all_fields = (_get_field(model, f) for f in model._meta.get_all_field_names())
    else:
        all_fields = model._meta.get_fields()
    for field in all_fields:
        # Django 1.8 +
        if (not RelatedObject and isinstance(field, OneToOneRel) and
                getattr(field.field.rel, "parent_link", None)):
            subclasses.extend(_get_subclasses(field.related_model))

        # < Django 1.8
        if (RelatedObject and isinstance(field, RelatedObject) and
                getattr(field.field.rel, "parent_link", None)):
            subclasses.extend(_get_subclasses(field.model))
    return subclasses
示例#9
0
    def similar_objects(self):
        lookup_kwargs = self._lookup_kwargs()
        lookup_keys = sorted(lookup_kwargs)
        qs = self.through.objects.values(*six.iterkeys(lookup_kwargs))
        qs = qs.annotate(n=models.Count('pk'))
        qs = qs.exclude(**lookup_kwargs)
        qs = qs.filter(tag__in=self.all())
        qs = qs.order_by('-n')

        # TODO: This all feels like a bit of a hack.
        items = {}
        if len(lookup_keys) == 1:
            # Can we do this without a second query by using a select_related()
            # somehow?
            f = _get_field(self.through, lookup_keys[0])
            remote_field = _remote_field(f)
            rel_model = _related_model(_remote_field(f))
            objs = rel_model._default_manager.filter(**{
                "%s__in" % remote_field.field_name: [r["content_object"] for r in qs]
            })
            for obj in objs:
                items[(getattr(obj, remote_field.field_name),)] = obj
        else:
            preload = {}
            for result in qs:
                preload.setdefault(result['content_type'], set())
                preload[result["content_type"]].add(result["object_id"])

            for ct, obj_ids in preload.items():
                ct = ContentType.objects.get_for_id(ct)
                model_class = ct.model_class()
                if model_class is None:
                    # obsolete content type. Skip it.
                    continue
                for obj in model_class._default_manager.filter(pk__in=obj_ids):
                    items[(ct.pk, obj.pk)] = obj

        results = []
        for result in qs:
            res_items = tuple(result[k] for k in lookup_keys)
            if res_items not in items:
                continue
            obj = items[res_items]
            obj.similar_tags = result["n"]
            results.append(obj)
        return results
示例#10
0
    def similar_objects(self):
        lookup_kwargs = self._lookup_kwargs()
        lookup_keys = sorted(lookup_kwargs)
        qs = self.through.objects.values(*six.iterkeys(lookup_kwargs))
        qs = qs.annotate(n=models.Count('pk'))
        qs = qs.exclude(**lookup_kwargs)
        qs = qs.filter(tag__in=self.all())
        qs = qs.order_by('-n')

        # TODO: This all feels like a bit of a hack.
        items = {}
        if len(lookup_keys) == 1:
            # Can we do this without a second query by using a select_related()
            # somehow?
            f = _get_field(self.through, lookup_keys[0])
            remote_field = _remote_field(f)
            rel_model = _related_model(_remote_field(f))
            objs = rel_model._default_manager.filter(
                **{
                    "%s__in" % remote_field.field_name:
                    [r["content_object"] for r in qs]
                })
            for obj in objs:
                items[(getattr(obj, remote_field.field_name), )] = obj
        else:
            preload = {}
            for result in qs:
                preload.setdefault(result['content_type'], set())
                preload[result["content_type"]].add(result["object_id"])

            for ct, obj_ids in preload.items():
                ct = ContentType.objects.get_for_id(ct)
                for obj in ct.model_class()._default_manager.filter(
                        pk__in=obj_ids):
                    items[(ct.pk, obj.pk)] = obj

        results = []
        for result in qs:
            obj = items[tuple(result[k] for k in lookup_keys)]
            obj.similar_tags = result["n"]
            results.append(obj)
        return results
示例#11
0
 def get_extra_join_sql(self, connection, qn, lhs_alias, rhs_alias):
     model_name = _model_name(self.through)
     if rhs_alias == "%s_%s" % (self.through._meta.app_label, model_name):
         alias_to_join = rhs_alias
     else:
         alias_to_join = lhs_alias
     extra_col = _get_field(self.through, "content_type").column
     content_type_ids = [ContentType.objects.get_for_model(subclass).pk for subclass in _get_subclasses(self.model)]
     if len(content_type_ids) == 1:
         content_type_id = content_type_ids[0]
         extra_where = " AND %s.%s = %%s" % (qn(alias_to_join), qn(extra_col))
         params = [content_type_id]
     else:
         extra_where = " AND %s.%s IN (%s)" % (
             qn(alias_to_join),
             qn(extra_col),
             ",".join(["%s"] * len(content_type_ids)),
         )
         params = content_type_ids
     return extra_where, params
示例#12
0
 def get_extra_join_sql(self, connection, qn, lhs_alias, rhs_alias):
     model_name = _model_name(self.through)
     if rhs_alias == '%s_%s' % (self.through._meta.app_label, model_name):
         alias_to_join = rhs_alias
     else:
         alias_to_join = lhs_alias
     extra_col = _get_field(self.through, 'content_type').column
     content_type_ids = [ContentType.objects.get_for_model(subclass).pk for
                         subclass in _get_subclasses(self.model)]
     if len(content_type_ids) == 1:
         content_type_id = content_type_ids[0]
         extra_where = " AND %s.%s = %%s" % (qn(alias_to_join),
                                             qn(extra_col))
         params = [content_type_id]
     else:
         extra_where = " AND %s.%s IN (%s)" % (qn(alias_to_join),
                                               qn(extra_col),
                                               ','.join(['%s'] *
                                                        len(content_type_ids)))
         params = content_type_ids
     return extra_where, params
示例#13
0
 def tag_relname(cls):
     return _get_field(cls, 'tag').rel.related_name
示例#14
0
 def m2m_reverse_field_name(self):
     return _get_field(self.through, 'tag').name
示例#15
0
 def tag_relname(cls):
     return _get_field(cls, 'tag').rel.related_name
示例#16
0
 def tag_model(cls):
     return _get_field(cls, 'tag').rel.to
示例#17
0
 def tag_relname(cls):
     field = _get_field(cls, 'tag')
     return field.remote_field.related_name if VERSION >= (
         1, 9) else field.rel.related_name
示例#18
0
 def tag_model(cls):
     field = _get_field(cls, 'tag')
     return field.remote_field.model if VERSION >= (1, 9) else field.rel.to
示例#19
0
 def related_fields(self):
     return [(_get_field(self.through, 'object_id'), self.model._meta.pk)]
示例#20
0
 def m2m_reverse_name(self):
     return _get_field(self.through, "tag").column
示例#21
0
 def tag_model(cls):
     return _get_field(cls, 'tag').rel.to
示例#22
0
 def tag_relname(cls):
     field = _get_field(cls, 'tag')
     return field.remote_field.related_name if VERSION >= (1, 9) else field.rel.related_name
示例#23
0
 def tag_model(cls):
     field = _get_field(cls, 'tag')
     return field.remote_field.model if VERSION >= (1, 9) else field.rel.to
示例#24
0
 def get_extra_restriction(self, where_class, alias, related_alias):
     extra_col = _get_field(self.through, 'content_type').column
     content_type_ids = [ContentType.objects.get_for_model(subclass).pk
                         for subclass in _get_subclasses(self.model)]
     return ExtraJoinRestriction(related_alias, extra_col, content_type_ids)
示例#25
0
 def related_fields(self):
     return [(_get_field(self.through, 'object_id'), self.model._meta.pk)]
示例#26
0
 def m2m_reverse_field_name(self):
     return _get_field(self.through, 'tag').name