Ticket #325 (closed defect: wontfix)

Opened 5 years ago

Last modified 15 months ago

Unable to access "get_for_model" method of the ContentTypes framework

Reported by: egmanoj@… Owned by: andrew
Priority: major Milestone:
Component: migrations Version: 0.6.2
Keywords: get_for_model ContentTypes Cc:

Description

When I execute the following code inside a migration I am getting an error:

content_type = orm['contenttypes.ContentType'].objects.get_for_model(orm.MyModel)

Error:

File "/usr/lib/python2.6/dist-packages/south/orm.py", line 361, in __getattr__
    return getattr(self.real, name)
AttributeError: 'Manager' object has no attribute 'get_for_model'

Interestingly the following works:

content_type = orm['contenttypes.ContentType'].objects.get(app_label='myapp', model='mymodel')

Version of South: 0.6.2
Version of Django: 1.1.1
Version of Python: 2.6

Change History

comment:1 Changed 5 years ago by andrew

  • Status changed from new to closed
  • Resolution set to wontfix

Yes, this is (unfortunately) by design; custom methods aren't carried over into frozen models. South 0.7 will have special generic relation/content type methods, but for now, you need to use get() instead of get_for_model():

ct = orm['contenttypes.ContentType'].get(app_label="myapp", model="mymodel") 

comment:2 Changed 21 months ago by anonymous

as of 0.7.6 you need .objects:

ct = orm['contenttypes.ContentType'].objects.get(app_label="myapp", model="mymodel") 

comment:3 Changed 15 months ago by Tobias McNulty <tobias@…>

One should note that the above method does not work if the content types don't exist yet, in which case you need to create them the way Django does. We wrote this little method for use in migrations:

from django.utils.encoding import smart_text

def get_content_type(orm, app_label, model_name):
    # sometimes these content types are not yet created when this migration runs,
    # so create them here.  mimic behavior of ContentType.objects.get_for_model
    # (which is not available in migrations)
    opts = orm['%s.%s' % (app_label, model_name)]._meta.concrete_model._meta
    return orm['contenttypes.ContentType'].objects.get_or_create(app_label=app_label,
              model=model_name, defaults={'name': smart_text(opts.verbose_name_raw)})
Note: See TracTickets for help on using tickets.