Index: django/models/auth.py
===================================================================
--- django/models/auth.py	(revision 2288)
+++ django/models/auth.py	(working copy)
@@ -2,6 +2,7 @@
 from django.models import core
 from django.utils.translation import gettext_lazy as _
 
+
 class Permission(meta.Model):
     name = meta.CharField(_('name'), maxlength=50)
     package = meta.ForeignKey(core.Package, db_column='package')
@@ -29,7 +30,94 @@
     def __repr__(self):
         return self.name
 
-class User(meta.Model):
+
+class UserUv2Constants(object):
+    """Constants for the UserUv2 class.
+    """
+    TYPE_DISTRIBUTOR = "D"
+    TYPE_ADMINISTRATOR = "A"
+    TYPE_PROCESSOR = "P"
+
+
+class UserUv2(UserUv2Constants):
+    """Base class for adding our custom fields to the django user model.
+    This model is inherited by django.models.auth.User
+    """
+    def get_payee(self):
+        """Returns this user's Payee object.
+        Returns None if this user is not associated with a payee.
+        """
+        try:
+            from django.models.uv2 import payees
+            return payees.get_object(u__id__exact=self.id)
+        except:
+            return None
+
+    def get_person(self):
+        """Returns this user's Person object.
+        Returns None if this user is not associated with a person.
+        """
+        try:
+            from django.models.uv2 import persons
+            return persons.get_object(u__id__exact=self.id)
+        except:
+            return None
+
+    def get_address(self):
+        """Returns this user's Address object.
+        Returns None if this user is not associated with an address.
+        """
+        try:
+            from django.models.uv2 import addresses
+            return addresses.get_object(u__id__exact=self.id)
+        except:
+            return None
+
+    def get_type(self):
+        """Returns the type of user this is.
+        Looks up the type in our persons table.
+        Returns None if this user is not associated with a person.
+        """
+        try:
+            p = self.get_person()
+            return p.type
+        except:
+            return None
+
+    def is_distributor(self):
+        """Returns true if this user is a uv2 Distributor.
+        Returns None if this user is not associated with a person.
+        """
+        try:
+            return self.get_type() == self.TYPE_DISTRIBUTOR
+        except:
+            return None
+    
+    def is_processor(self):
+        """Returns true if this user is a uv2 Processor.
+        Returns None if this user is not associated with a person.
+        """
+        try:
+            return self.get_type() == self.TYPE_PROCESSOR
+        except:
+            return None
+    
+    
+    def is_administrator(self):
+        """Returns true if this user is a uv2 Administrator.
+        Returns None if this user is not associated with a person.
+        """
+        try:
+            return self.get_type() == self.TYPE_ADMINISTRATOR
+        except:
+            return None
+    
+    
+    class META:
+        no_table = True
+
+
+class User(meta.Model, UserUv2):
     username = meta.CharField(_('username'), maxlength=30, unique=True, validator_list=[validators.isAlphaNumeric])
     first_name = meta.CharField(_('first name'), maxlength=30, blank=True)
     last_name = meta.CharField(_('last name'), maxlength=30, blank=True)
@@ -66,6 +154,7 @@
 
     def __repr__(self):
         return self.username
+        #return "User is a distributor: %s" % self.is_distributor()
 
     def get_absolute_url(self):
         return "/users/%s/" % self.username
Index: django/core/meta/__init__.py
===================================================================
--- django/core/meta/__init__.py	(revision 2288)
+++ django/core/meta/__init__.py	(working copy)
@@ -625,6 +625,11 @@
         # attribute order.
         fields.sort(lambda x, y: x.creation_counter - y.creation_counter)
 
+        # Should this class generate database tables (Default is Yes)?
+        # This has the ultimate effect of keeping this class out of the _MODELS
+        # list.
+        create_table = not (meta_attrs.pop('no_table', False))
+
         # If this model is a subclass of another model, create an Options
         # object by first copying the base class's _meta and then updating it
         # with the overrides from this class.
@@ -889,7 +894,9 @@
             # contain this list:
             # [<class 'django.models.polls.Poll'>, <class 'django.models.polls.Choice'>]
             # Don't do this if replaces_module is set.
-            app_package.__dict__.setdefault('_MODELS', []).append(new_class)
+            # Exclude models where the user has set 'no_table = True'
+            if create_table:
+                app_package.__dict__.setdefault('_MODELS', []).append(new_class)
 
         # Cache the app label.
         opts.app_label = app_label
@@ -938,6 +945,7 @@
     def __repr__(self):
         return '<%s object>' % self.__class__.__name__
 
+
 ############################################
 # HELPER FUNCTIONS (CURRIED MODEL METHODS) #
 ############################################
@@ -1027,6 +1035,16 @@
         if opts.has_auto_field and not pk_set:
             setattr(self, opts.pk.attname, db.get_last_insert_id(cursor, opts.db_table, opts.pk.column))
     db.db.commit()
+    
+    # Update the auto_now and auto_now_add fields to the values just inserted
+    # into the database
+    i = 0
+    for f in non_pks:
+        if isinstance(f, DateField):
+            if f.auto_now or (f.auto_now_add and not record_exists):
+                setattr(self, f.attname, db_values[i])
+        i += 1
+
     # Run any post-save hooks.
     if hasattr(self, '_post_save'):
         self._post_save()
Index: django/core/template/loader.py
===================================================================
--- django/core/template/loader.py	(revision 2288)
+++ django/core/template/loader.py	(working copy)
@@ -103,6 +103,20 @@
         context_instance = Context(dictionary)
     return t.render(context_instance)
 
+def render_to_file(template_name, file_path, mode='w', dictionary=None, context_instance=None):
+    """
+    Loads the given template_name and renders it, with the given dictionary as
+    context, to a file on disk.  The template_name may be a string to load a
+    single template using get_template, or it may be a tuple to use
+    select_template to find one of the templates in the list.  file_path defines
+    the file that will be written to disk.  mode defaults to 'w' which will
+    create the file if it doesn't exist and will overwrite the file if it does
+    exist.
+    """
+    f = open(file_path, mode)
+    f.write(render_to_string(template_name, dictionary, context_instance))
+    f.close()
+
 def select_template(template_name_list):
     "Given a list of template names, returns the first that can be loaded."
     for template_name in template_name_list:
Index: docs/db-api.txt
===================================================================
--- docs/db-api.txt	(revision 2288)
+++ docs/db-api.txt	(working copy)
@@ -173,7 +173,7 @@
     in           In a given list: ``polls.get_list(id__in=[1, 3, 4])`` returns
                  a list of polls whose IDs are either 1, 3 or 4.
     startswith   Case-sensitive starts-with:
-                 ``polls.get_list(question_startswith="Would")``. (PostgreSQL
+                 ``polls.get_list(question__startswith="Would")``. (PostgreSQL
                  and MySQL only. SQLite doesn't support case-sensitive LIKE
                  statements; ``startswith`` will act like ``istartswith`` for
                  SQLite.)
