Opened 11 years ago

Closed 10 years ago

Last modified 10 years ago

#22690 closed Bug (fixed)

'Proxy model contains model fields' error

Reported by: Craig de Stigter Owned by: nobody
Component: Database layer (models, ORM) Version: 1.7-beta-2
Severity: Release blocker Keywords:
Cc: cmawebsite@… Triage Stage: Ready for checkin
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

My django-typed-models extension implements a type-field based model inheritance approach for django using proxy models.

It relies on having proxy models with their own fields, which has always worked with minimal hackery until recently.

Now on Django 1.7, we are getting this issue (ticket):

cdestigter@bob:~/c/tp$ ./manage.py syncdb
eh
Operations to perform:
  Synchronize unmigrated apps: admin, contenttypes, auth, sessions
  Apply all migrations: (none)
Synchronizing apps without migrations:
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Running migrations:
  No migrations needed.
Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/cdestigter/checkout/django/django/core/management/__init__.py", line 427, in execute_from_command_line
    utility.execute()
  File "/Users/cdestigter/checkout/django/django/core/management/__init__.py", line 419, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/cdestigter/checkout/django/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Users/cdestigter/checkout/django/django/core/management/base.py", line 337, in execute
    output = self.handle(*args, **options)
  File "/Users/cdestigter/checkout/django/django/core/management/base.py", line 532, in handle
    return self.handle_noargs(**options)
  File "/Users/cdestigter/checkout/django/django/core/management/commands/syncdb.py", line 24, in handle_noargs
    call_command("migrate", **options)
  File "/Users/cdestigter/checkout/django/django/core/management/__init__.py", line 167, in call_command
    return klass.execute(*args, **defaults)
  File "/Users/cdestigter/checkout/django/django/core/management/base.py", line 337, in execute
    output = self.handle(*args, **options)
  File "/Users/cdestigter/checkout/django/django/core/management/commands/migrate.py", line 141, in handle
    changes = autodetector.changes(graph=executor.loader.graph)
  File "/Users/cdestigter/checkout/django/django/db/migrations/autodetector.py", line 36, in changes
    changes = self._detect_changes()
  File "/Users/cdestigter/checkout/django/django/db/migrations/autodetector.py", line 54, in _detect_changes
    new_apps = self.to_state.render()
  File "/Users/cdestigter/checkout/django/django/db/migrations/state.py", line 64, in render
    model.render(self.apps)
  File "/Users/cdestigter/checkout/django/django/db/migrations/state.py", line 270, in render
    body,
  File "/Users/cdestigter/checkout/django/django/db/models/base.py", line 198, in __new__
    raise FieldError("Proxy model '%s' contains model fields." % name)
django.core.exceptions.FieldError: Proxy model 'Hub' contains model fields.

This FieldError seems unnecessary and is not easily overridden without overriding the whole of ModelBase.__new__.

Can this FieldError please be removed (or extracted into a method that can be overridden, so I can remove this check for consenting subclasses)?

Otherwise I fear I may end up having to copy all 229 lines of ModelBase.__new__ into my code just to maintain this.

tested on latest 1.7.x.

Seems related: #22568

Marked as blocker cos it seems like a regression. Doesn't happen on 1.6.x or earlier

Change History (7)

comment:1 by Simon Charette, 10 years ago

I'm not convinced this is something we want to support at all but I guess we could convert this to a check instead?

comment:2 by Craig de Stigter, 10 years ago

Checks! Those look promising. Perhaps in Model._check_fields()?

That would work well for my app as I would only need to override that (much smaller) method to remove the check.

comment:3 by Craig de Stigter, 10 years ago

I've submitted a pull request for this: https://github.com/django/django/pull/2733

I ended up adding a new private method instead of putting it in Model._check_fields because it looks like 'field checks' are specific to a particular field, whereas this check is not so it seemed like it didn't belong there.

I'm not very familiar with checks but hopefully this can be quickly massaged into something adequate :)

comment:4 by Anssi Kääriäinen, 10 years ago

Triage Stage: UnreviewedReady for checkin

Looks good to me. This doesn't add any official support for proxy models with fields, but if users have existing code using proxy models with fields, then it will be possible to silence the error. Also, check instead of FieldError seems to be consistent with how other similar errors are handled.

comment:5 by Tim Graham <timograham@…>, 10 years ago

Resolution: fixed
Status: newclosed

In ce993efda876b19569267badb6af5fd0e80cdee3:

Fixed #22690 -- Added a check for proxy models containing fields.

Removed the FieldError raised by ModelBase.new in this case.

comment:6 by Tim Graham <timograham@…>, 10 years ago

In 724e6008722acb9b69ea3d1749ac8c1125837d03:

[1.7.x] Fixed #22690 -- Added a check for proxy models containing fields.

Removed the FieldError raised by ModelBase.new in this case.

Backport of ce993efda8 from master

comment:7 by Collin Anderson, 10 years ago

Cc: cmawebsite@… added

I also am using model fields on proxy models and I'll add overriding _check_model to my hacky code. (How else do you get virtual, non-database fields to show up both on the model _and_ in the admin?)

Note: See TracTickets for help on using tickets.
Back to Top