I am running a Django 1.4.2 project. I have a database of class User(models.Model), and would now like to change this so that I used the built in model User from django.contrib.auth.models. Can I simply use my existing code and simply make my own custon User model a subclass of Django's built in one? Here is the model now.
class User(models.Model):
u_id = models.AutoField(primary_key=True)
#password = models.CharField(max_length=765)
old_password = models.CharField(max_length=765, null=True, blank=True)
birthday = models.DateField(null=True, blank=True)
school_year = models.CharField(max_length=765, blank=True)
gender = models.CharField(max_length=18, blank=True)
#email = models.CharField(max_length=765, blank=True)
profile_pic = models.CharField(max_length=765, blank=True)
is_cloudinary_pic = models.BooleanField(default=False)
fb_id = models.CharField(max_length=765, blank=True)
phone_num = models.CharField(max_length=765, blank=True)
name = models.CharField(max_length=765, blank=True)
confirmcode = models.CharField(max_length=765, blank=True)
status = models.CharField(max_length=765, blank=True)
netid = models.CharField(max_length=765, blank=True)
favorites = models.ManyToManyField('listings.Listing', blank=True, related_name='favorites')
stripe = models.CharField(max_length=765, blank=True)
rating = models.IntegerField(null=True, blank=True)
preferences = models.CharField(max_length=765, blank=True)
b_notification = models.CharField(max_length=765, blank=True)
l_notification = models.CharField(max_length=765, blank=True)
address = models.CharField(max_length=765, blank=True)
city = models.CharField(max_length=765, blank=True)
state = models.CharField(max_length=6, blank=True)
zip = models.CharField(max_length=15, blank=True)
emailprefs = models.CharField(max_length=30, blank=True)
exp_month = models.CharField(max_length=6, blank=True)
exp_year = models.CharField(max_length=12, blank=True)
last4 = models.CharField(max_length=12, blank=True)
c_type = models.CharField(max_length=765, blank=True)
user_type = models.CharField(max_length=10, blank=True)
contract = models.ForeignKey('contracts.Contract', null=True,blank=True, default=None, on_delete=models.SET_NULL)
last_listing_booked = models.ForeignKey('listings.Listing', null=True,blank=True, default=None, on_delete=models.SET_NULL, related_name='last_listing_booked')
last_locked_on = models.IntegerField(null=True, blank=True)
waitlist_number = models.IntegerField(null=True, blank=True)
waitlist_listing = models.ForeignKey('listings.Listing', null=True, blank=True, on_delete=models.SET_NULL, related_name='waitlist_listing')
uploaded_contract = models.FileField(upload_to=contract_file_name, max_length=765, null=True, blank=True, default=None, storage=FileSystemStorage(location=os.path.join(MEDIA_ROOT, 'contracts')))
When I try to migrate using Django South after making my model a subclass of the Django User model, I am asked to set a value for user_ptr, a field about which I have been unsuccessful finding any information.
In general, is it unsafe to simply subclass in this fashion? I cannot afford to lose all the user data I already have and start over. Note that the password and email fields are commented out because they clash with Django's version of those fields.
If upgrading to Django 1.5 is an option, you can simply use your own User model, so long as it supplies all the required fields.
user_ptr is an implicit OneToOne model that associates your object with the class you're deriving from. The easiest way to do this would probably be to create the migration manually in these steps:
Add the user_ptr field WITH null=True
Iterate over all the User objects and create the corresponding auth.User objects. If you are unsure of how to do this, you can read the section on data migrations in the South documentation.
Disallow null user_ptr fields
Another thing you might need to do is implement your own password hasher if the hashing scheme you used isn't compatible with Django's built in methods. This is not very hard to do, and is addressed in another question.
If using Django 1.4, you should create a UserProfile
model instead of sub-classing from django.contrib.auth.models.User
. Extending Django's User class directly can cause all kinds of trouble with the internal django.auth mechanisms.
You can read more about how to implement user profiles in django at http://www.turnkeylinux.org/blog/django-profile.
Django 1.5 has configurable user model as mentioned in another answer by Vinay Pai.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With