Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Handle non-default kwargs in deconstruct #207

Merged
merged 4 commits into from

2 participants

@blueyed

According to the documentation [1], non-default kwargs need to get
returned.

1: https://docs.djangoproject.com/en/dev/howto/custom-model-fields/#field-deconstruction

@apollo13
Collaborator

@blueyed Shouldn't django/django@6b07804 take care of this?

@blueyed

@apollo13
django/django@6b07804 only handles rel.through (i.e. the one from TaggableRel), but TaggableManager's through is different.

Any idea why the tests are failing for Django < 1.7?

CommandError: One or more models did not validate:
tests.multipletagsgfk: 'tags2' is a manually-defined m2m relation through model ThroughGFK, which does not have foreign keys to Tag and MultipleTagsGFK

blueyed added some commits
@blueyed blueyed Merge branch 'develop' into deconstruct-keep-non-defaults
This probably fixes the travis builds.

Conflicts:
	taggit/managers.py
0cc67dc
@blueyed blueyed Handle "to" with deconstruction
This accepts "to" as kwarg, and provides it via `deconstruct`, and also
changes `deconstruct` to always provide/set "through".

This is more explicit and since the manager always uses a through model
internally, this describes it better.
6e9043a
@apollo13
Collaborator

This fails on everything but 1.7

@blueyed

Ah, the test itself is failing:

Traceback (most recent call last):
AttributeError: 'super' object has no attribute 'deconstruct'

How should this get handled? Skipping the test for Django < 1.7?

@apollo13
Collaborator

Jupp, noone needs deconstruct on 1.6 ;)

@blueyed

Hmm, travis does not appear to pickup this commit/update.

I guess I should rebase the commits anyway, if it looks OK for you in general?!

@apollo13 apollo13 merged commit 8fb7cfa into from
@apollo13
Collaborator

It didn't pick it up cause it had merge conflicts.

@blueyed blueyed deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 13, 2014
  1. @blueyed

    Handle non-default kwargs in deconstruct

    blueyed authored
    According to the documentation [1], non-default kwargs need to get
    returned.
    
    1: https://docs.djangoproject.com/en/dev/howto/custom-model-fields/#field-deconstruction
Commits on Mar 20, 2014
  1. @blueyed

    Merge branch 'develop' into deconstruct-keep-non-defaults

    blueyed authored
    This probably fixes the travis builds.
    
    Conflicts:
    	taggit/managers.py
  2. @blueyed

    Handle "to" with deconstruction

    blueyed authored
    This accepts "to" as kwarg, and provides it via `deconstruct`, and also
    changes `deconstruct` to always provide/set "through".
    
    This is more explicit and since the manager always uses a through model
    internally, this describes it better.
Commits on Apr 4, 2014
  1. @blueyed
This page is out of date. Refresh to see the latest.
Showing with 20 additions and 1 deletion.
  1. +10 −1 taggit/managers.py
  2. +10 −0 tests/tests.py
View
11 taggit/managers.py
@@ -73,11 +73,12 @@ class TaggableManager(RelatedField, Field):
_related_name_counter = 0
def __init__(self, verbose_name=_("Tags"), help_text=_("A comma-separated list of tags."),
- through=None, blank=False, related_name=None):
+ through=None, blank=False, related_name=None, to=None):
Field.__init__(self, verbose_name=verbose_name, help_text=help_text, blank=blank, null=True, serialize=False)
self.through = through or TaggedItem
self.rel = TaggableRel(self, related_name, self.through)
self.swappable = False
+ # NOTE: `to` is ignored, only used via `deconstruct`.
def __get__(self, instance, model):
if instance is not None and instance.pk is None:
@@ -92,9 +93,17 @@ def __get__(self, instance, model):
return manager
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
+ kwargs['through'] = self.through
+ kwargs['to'] = self.through._meta.get_field("tag").rel.to
return name, path, args, kwargs
def contribute_to_class(self, cls, name):
View
10 tests/tests.py
@@ -1,6 +1,7 @@
from __future__ import unicode_literals, absolute_import
from unittest import TestCase as UnitTestCase
+from unittest import skipIf
import django
from django.conf import settings
@@ -538,3 +539,12 @@ def test_recreation_of_tag_list_string_representations(self):
self.assertEqual(edit_string_for_tags([plain, spaces, comma]), '"com,ma", "spa ces", plain')
self.assertEqual(edit_string_for_tags([plain, comma]), '"com,ma", plain')
self.assertEqual(edit_string_for_tags([comma, spaces]), '"com,ma", "spa ces"')
+
+
+@skipIf(django.VERSION < (1, 7), "not relevant for Django < 1.7")
+class DeconstructTestCase(UnitTestCase):
+ def test_deconstruct_kwargs_kept(self):
+ instance = TaggableManager(through=OfficialThroughModel)
+ name, path, args, kwargs = instance.deconstruct()
+ new_instance = TaggableManager(*args, **kwargs)
+ self.assertEqual(instance.rel.through, new_instance.rel.through)
Something went wrong with that request. Please try again.