Beispiel #1
0
 def test_deconstruct_kwargs_kept(self):
     instance = TaggableManager(through=OfficialThroughModel, to='dummy.To')
     name, path, args, kwargs = instance.deconstruct()
     new_instance = TaggableManager(*args, **kwargs)
     self.assertEqual('tests.OfficialThroughModel',
                      _remote_field(new_instance).through)
     self.assertEqual('dummy.To',
                      _related_model(_remote_field(new_instance)))
def _get_subclasses(model):
    subclasses = [model]
    for field in model._meta.get_fields():
        if isinstance(field, OneToOneRel) and getattr(
                _remote_field(field.field), "parent_link", None):
            subclasses.extend(_get_subclasses(field.related_model))
    return subclasses
    def deconstruct(self):
        """
        Deconstruct the object, used with migrations.
        """
        name, path, args, kwargs = super(TaggableManager, self).deconstruct()
        # Remove forced kwargs.
        for kwarg in ('serialize', 'null'):
            del kwargs[kwarg]
        # Add arguments related to relations.
        # Ref: https://github.com/alex/django-taggit/issues/206#issuecomment-37578676
        rel = _remote_field(self)
        if isinstance(rel.through, six.string_types):
            kwargs['through'] = rel.through
        elif not rel.through._meta.auto_created:
            kwargs['through'] = "%s.%s" % (rel.through._meta.app_label,
                                           rel.through._meta.object_name)

        related_model = _related_model(rel)
        if isinstance(related_model, six.string_types):
            kwargs['to'] = related_model
        else:
            kwargs['to'] = '%s.%s' % (related_model._meta.app_label,
                                      related_model._meta.object_name)

        return name, path, args, kwargs
Beispiel #4
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]
            })
            actual_remote_field_name = remote_field.field_name
            if VERSION > (1, 9):
                actual_remote_field_name = f.target_field.get_attname()
            else:
                actual_remote_field_name = f.related_field.get_attname()
            for obj in objs:
                items[(getattr(obj, actual_remote_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
    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 = self.through._meta.get_field(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
Beispiel #6
0
    def test_field_api(self):
        # Check if tag field, which simulates m2m, has django-like api.
        field = self.food_model._meta.get_field('tags')
        if django.VERSION >= (1, 9):
            self.assertTrue(hasattr(field, 'remote_field'))
            self.assertTrue(hasattr(field.remote_field, 'model'))
        else:
            self.assertTrue(hasattr(field, 'rel'))
            self.assertTrue(hasattr(field.rel, 'to'))

        self.assertEqual(self.food_model, field.model)
        self.assertEqual(self.tag_model, _remote_field(field).model)
Beispiel #7
0
    def test_field_api(self):
        # Check if tag field, which simulates m2m, has django-like api.
        field = self.food_model._meta.get_field('tags')
        if django.VERSION >= (1, 9):
            self.assertTrue(hasattr(field, 'remote_field'))
            self.assertTrue(hasattr(field.remote_field, 'model'))
        else:
            self.assertTrue(hasattr(field, 'rel'))
            self.assertTrue(hasattr(field.rel, 'to'))

        self.assertEqual(self.food_model, field.model)
        self.assertEqual(self.tag_model, _remote_field(field).model)
 def _get_gfk_case_path_info(self, direct=False, filtered_relation=None):
     pathinfos = []
     from_field = self.model._meta.pk
     opts = self.through._meta
     linkfield = self.through._meta.get_field(self.m2m_reverse_field_name())
     if direct:
         if VERSION < (2, 0):
             join1infos = [PathInfo(self.model._meta, opts, [from_field], _remote_field(self), True, False)]
             join2infos = linkfield.get_path_info()
         else:
             join1infos = [PathInfo(self.model._meta, opts, [from_field], _remote_field(self), True, False, filtered_relation)]
             join2infos = linkfield.get_path_info(filtered_relation=filtered_relation)
     else:
         if VERSION < (2, 0):
             join1infos = linkfield.get_reverse_path_info()
             join2infos = [PathInfo(opts, self.model._meta, [from_field], self, True, False)]
         else:
             join1infos = linkfield.get_reverse_path_info(filtered_relation=filtered_relation)
             join2infos = [PathInfo(opts, self.model._meta, [from_field], self, True, False, filtered_relation)]
     pathinfos.extend(join1infos)
     pathinfos.extend(join2infos)
     return pathinfos
Beispiel #9
0
    def test_field_api(self):
        # Check if tag field, which simulates m2m, has django-like api.
        field = self.food_model._meta.get_field('tags')
        if django.VERSION >= (1, 9):
            self.assertTrue(hasattr(field, 'remote_field'))
            self.assertTrue(hasattr(field.remote_field, 'model'))
        elif django.VERSION >= (1, 8):
            self.assertTrue(hasattr(field, 'rel'))
            self.assertTrue(hasattr(field.rel, 'to'))
        else:
            self.assertTrue(hasattr(field, 'rel'))
            self.assertTrue(hasattr(field.rel, 'to'))

        # This API has changed in Django 1.8
        # https://code.djangoproject.com/ticket/21414
        if django.VERSION >= (1, 9):
            self.assertEqual(self.food_model, field.model)
            self.assertEqual(self.tag_model, _remote_field(field).model)
        if django.VERSION >= (1, 8):
            self.assertEqual(self.food_model, field.model)
            self.assertEqual(self.tag_model, _remote_field(field).model)
        else:
            self.assertEqual(self.food_model, field.related.model)
Beispiel #10
0
    def test_field_api(self):
        # Check if tag field, which simulates m2m, has django-like api.
        field = self.food_model._meta.get_field('tags')
        if django.VERSION >= (1, 9):
            self.assertTrue(hasattr(field, 'remote_field'))
            self.assertTrue(hasattr(field.remote_field, 'model'))
        elif django.VERSION >= (1, 8):
            self.assertTrue(hasattr(field, 'rel'))
            self.assertTrue(hasattr(field.rel, 'to'))
        else:
            self.assertTrue(hasattr(field, 'rel'))
            self.assertTrue(hasattr(field.rel, 'to'))

        # This API has changed in Django 1.8
        # https://code.djangoproject.com/ticket/21414
        if django.VERSION >= (1, 9):
            self.assertEqual(self.food_model, field.model)
            self.assertEqual(self.tag_model, _remote_field(field).model)
        if django.VERSION >= (1, 8):
            self.assertEqual(self.food_model, field.model)
            self.assertEqual(self.tag_model, _remote_field(field).model)
        else:
            self.assertEqual(self.food_model, field.related.model)
Beispiel #11
0
 def _get_gfk_case_path_info(self, direct=False):
     pathinfos = []
     from_field = self.model._meta.pk
     opts = self.through._meta
     linkfield = _get_field(self.through, self.m2m_reverse_field_name())
     if direct:
         join1infos = [PathInfo(self.model._meta, opts, [from_field], _remote_field(self), True, False)]
         join2infos = linkfield.get_path_info()
     else:
         join1infos = linkfield.get_reverse_path_info()
         join2infos = [PathInfo(opts, self.model._meta, [from_field], self, True, False)]
     pathinfos.extend(join1infos)
     pathinfos.extend(join2infos)
     return pathinfos
Beispiel #12
0
 def _get_gfk_case_path_info(self, direct=False):
     pathinfos = []
     from_field = self.model._meta.pk
     opts = self.through._meta
     linkfield = _get_field(self.through, self.m2m_reverse_field_name())
     if direct:
         join1infos = [PathInfo(self.model._meta, opts, [from_field], _remote_field(self), True, False)]
         join2infos = linkfield.get_path_info()
     else:
         join1infos = linkfield.get_reverse_path_info()
         join2infos = [PathInfo(opts, self.model._meta, [from_field], self, True, False)]
     pathinfos.extend(join1infos)
     pathinfos.extend(join2infos)
     return pathinfos
Beispiel #13
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(_remote_field(field.field), "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
Beispiel #14
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(_remote_field(field.field), "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
Beispiel #15
0
    def deconstruct(self):
        """
        Deconstruct the object, used with migrations.
        """
        name, path, args, kwargs = super(TaggableManager, self).deconstruct()
        # Remove forced kwargs.
        for kwarg in ('serialize', 'null'):
            del kwargs[kwarg]
        # Add arguments related to relations.
        # Ref: https://github.com/alex/django-taggit/issues/206#issuecomment-37578676
        rel = _remote_field(self)
        if isinstance(rel.through, six.string_types):
            kwargs['through'] = rel.through
        elif not rel.through._meta.auto_created:
            kwargs['through'] = "%s.%s" % (rel.through._meta.app_label, rel.through._meta.object_name)

        related_model = _related_model(rel)
        if isinstance(related_model, six.string_types):
            kwargs['to'] = related_model
        else:
            kwargs['to'] = '%s.%s' % (related_model._meta.app_label, related_model._meta.object_name)

        return name, path, args, kwargs
Beispiel #16
0
def _get_subclasses(model):
    subclasses = [model]
    for field in model._meta.get_fields():
        if isinstance(field, OneToOneRel) and getattr(_remote_field(field.field), "parent_link", None):
            subclasses.extend(_get_subclasses(field.related_model))
    return subclasses
Beispiel #17
0
 def test_deconstruct_kwargs_kept(self):
     instance = TaggableManager(through=OfficialThroughModel, to='dummy.To')
     name, path, args, kwargs = instance.deconstruct()
     new_instance = TaggableManager(*args, **kwargs)
     self.assertEqual('tests.OfficialThroughModel', _remote_field(new_instance).through)
     self.assertEqual('dummy.To', _related_model(_remote_field(new_instance)))
 def resolve_related_class(field, model, cls):
     self.through = model
     _remote_field(self).through = model
     self.post_through_setup(cls)