I'm trying to extend the built-in user and add some more information to it. I have two apps in my django project- general and user_details. Inside my user_details app, in the models.py file, I have the following...
from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from general.models import Ward
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
firstname = models.CharField(max_length=20)
middlename = models.CharField(max_length=20)
lastname = models.CharField(max_length=20)
loc_id = models.CharField(max_length=8, unique=True)
ward = models.ForeignKey(Ward, related_name="wards", on_delete=models.CASCADE)
phone = models.CharField(max_length=10, unique=True)
address = models.CharField(max_length=255)
postal_code = models.CharField(max_length=15)
def __str__(self):
return "{} {}".format(self.user.first_name, self.user.last_name)
class Meta:
verbose_name_plural = "User details"
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
else:
instance.profile.save()
I have successfully done this before but today for some reason when I try to log in via the django admin, I keep getting the RelatedObjectDoesNotExist at /admin/login/, no such column: user_details_profile.id. There are no other components involved, no views or any of that. It's just models and the admin panel. I'm trying to get the model to show in the admin panel but I ran into this error every time I try to log in.
Here is the traceback http://dpaste.com/0W7653C.
Can anyone tell me what I am doing wrong please and how I can get it to work. Help.
Django admin allows access to users marked as is_staff=True . To disable a user from being able to access the admin, you should set is_staff=False . This holds true even if the user is a superuser. is_superuser=True .
First of all: Inside your INSTALLED_APPS tuple, in settings.py you have to enable: 'django. contrib. admin' . Second: you have to run python manage.py syncdb after you enable the Django admin app.
No. The django admin is not intended for any end-user. The django admin feature is intended to assist the website developer, and that is all.
If you define a OneToOneField that does not mean that every object of the targeted model contains an object from the referencing model. A OneToOneField in essence is a ForeignKey with a unique=True (and some extra logic to do proper naming).
Here it thus means that although every Profile has a related user, not every user has a Profile. It is possible that there are Users for which no Profile exists.
If you thus query some_user.profile there are two scenario's that can unfold:
Profile object that is the fetched, and returned; orRelatedObjectDoesNotExist error.There have been some proposals to return None in the latter case, but due to backwards compatibility, this will probably not be implemented in the (near) future, or implemented at all.
So you probably have a user for which there is no profile. Based on the full traceback, the error happens on the line instance.profile.save(). We can fix this by creating a profile in case there is no such profile:
from django.core.exceptions import ObjectDoesNotExist
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
try:
instance.profile.save()
except ObjectDoesNotExist:
Profile.objects.create(user=instance)
We thus check if the instance has a .profile that leads to a Profile object. In case it has not, it will raise an exception, and then we create one.
This is also more in the Easier to Ask Forgiveness than Permission (EAFP) spirit of Django.
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