title: Extending auth.User model, proxied fields, and Django admin
body: <p>(Edit:  I know that there's a totally separate feature in Django called "Proxy Models".  That feature doesn't help me, because I need to be able to add fields to UserProfile.)</p>
  
  <p>So I'm starting a new Django app and I'm creating a UserProfile model which is a extension of django.contrib.auth.models.User and failed attribute requests back to User, as follows:</p>
  
  <pre><code>from django.db import models
  from django.contrib.auth.models import User
  
  class UserProfile(models.Model):
      user = models.OneToOneField(User, related_name='profile')
  
      def __getattr__(self, name, *args):
          if name == 'user' or name == '_user_cache':
              raise AttributeError(name)
  
          try:
              return getattr(self.user, name, *args)
          except AttributeError, e:
              raise AttributeError(name)
  </code></pre>
  
  <p>This works fine in general, but breaks when I try to use a <code>User</code> field in UserProfileAdmin.list_display.  The problem is in the admin validation code here:</p>
  
  <pre><code>def validate(cls, model):
      """
      Does basic ModelAdmin option validation. Calls custom validation
      classmethod in the end if it is provided in cls. The signature of the
      custom validation classmethod should be: def validate(cls, model).
      """
      # Before we can introspect models, they need to be fully loaded so that
      # inter-relations are set up correctly. We force that here.
      models.get_apps()
  
      opts = model._meta
      validate_base(cls, model)
  
      # list_display
      if hasattr(cls, 'list_display'):
          check_isseq(cls, 'list_display', cls.list_display)
          for idx, field in enumerate(cls.list_display):
              if not callable(field):
                  if not hasattr(cls, field):
                      if not hasattr(model, field):
                          try:
                              opts.get_field(field)
                          except models.FieldDoesNotExist:
                              raise ImproperlyConfigured("%s.list_display[%d], %r is not a callable or an attribute of %r or found in the model %r."
                                  % (cls.__name__, idx, field, cls.__name__, model._meta.object_name))
  </code></pre>
  
  <p>The problem is that while an instance of UserProfile will have proxied fields, e.g. email, the UserProfile class itself doesn't.  Demoed in the Django shell:</p>
  
  <pre><code>&gt;&gt;&gt; hasattr(UserProfile, 'email')
  False
  &gt;&gt;&gt; hasattr(UserProfile.objects.all()[0], 'email')
  True
  </code></pre>
  
  <p>After some digging, it looks like I'd want to override django.db.models.options.Options.get_field for UserProfile._meta.  But there doesn't seem to be a non-hacky way to do this (I have a very hacky solution right now, which involves monkey-patching UserProfile._meta.[get_field, get_field_by_name])...any suggestions?  Thanks.</p>