0

I have added a Target model in my app that tags a Revision object (from django-reversion) through a one-to-one field. The tag depends on the objects in the version set, and if any of these objects requires a tag, then the tag should be set for the entire revision. I am trying to use a django-south data migration to iterate through all the Revision objects in my database, check each object in the associated version_set, and set the tag if necessary.

class Migration(DataMigration):

    def forwards(self, orm):
        for revision in orm["reversion.Revision"].objects.all():
            try:
                revision.target # the revision is already tagged
            except: # revision.target raises different sorts of DoesNotExist errors, 
                    # and I can't work out how to catch all of them
                for version in revision.version_set.all():
                    try:
                        tag = version.object.get_tag() # all models in my app that   
                        orm.Target.objects.create(     # specify tags have this method
                                revision=revision, 
                                tag=tag)
                        break
                    except AttributeError: # the version set doesn't contain any
                        pass               # models that specify a tag

The gives an error:

    [... lots of stuff cut ...], line 21, in forwards
    for version in revision.version_set.all():
AttributeError: 'Revision' object has no attribute 'version_set'

How can I get access to the version_set of a Revision object during a datamigration in a different app?

EDIT Thanks to Daniel I'm further along. In the following code I try to access all models via the Migration's own orm:

def forwards(self, orm):
    my_models = { # models with a .get_tag() method
            "modela": orm.ModelA,
            "modelb": orm.ModelB,
            }
    for revision in orm["reversion.Revision"].objects.all():
        for version in orm["reversion.Version"].objects.filter(revision=revision):
            try:
                model = my_models[version.content_type.model]
                instance = model.objects.get(id=version.object_id)
                tag = instance.get_tag()
                orm.RevisionTargetLanguage.objects.create(
                        revision=revision,
                        tag=tag)
                break
            except KeyError: # not one of the models with a .get_tag() method
                pass

This fails at the line instance = model.objects.get(id=version.object_id_int) with the exception DoesNotExist: ModelB matching query does not exist.

Michael Dunn
  • 8,163
  • 4
  • 37
  • 54

1 Answers1

1

You could try

orm['reversion.Version'].objects.filter(revision=revision)
ProgramFOX
  • 6,131
  • 11
  • 45
  • 51
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • This is getting me in the right direction. I got an error "The model 'version' from the app 'reversion' is not available in this migration. I added 'version' to the data migration instance's models attribute (from http://stackoverflow.com/questions/19400149/django-south-how-can-i-access-models-in-sub-packages-in-migrations), but then I think I have a similar problem: the version.object.get_tag() call always raises an AttributeError -- presumably because the object represented by version.object is not available. – Michael Dunn Mar 28 '14 at 15:11