I am receiving an error when making the following query:
Election.objects.all().exclude(candidate__UserID=request.user).filter(Gender=request.user.Profile.Gender).filter(CandidateReg=True)
To this model:
class Election(models.Model):
Name = models.CharField(max_length=20)
CandidateReg = models.BooleanField(default=True)
VotingOpen = models.BooleanField(default=False)
Description = models.CharField(max_length=255, null=True, blank=True)
GENDERS = (("M","Male"), ("F","Female"))
Gender = models.CharField(max_length=1, choices=GENDERS, default="M")
Seats = models.IntegerField(default=7)
FlipGrid = models.URLField(null=True, blank=True)
Complete = models.BooleanField(default=False)
The problem is described in this error:
Traceback (most recent call last):
File "/home/elections/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/home/elections/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/elections/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/elections/elections-real/elections/views.py", line 139, in add_candidate
elections = Election.objects.all().exclude(candidate__UserID=request.user).filter(Gender=request.user.Profile.Gender).filter(CandidateReg=True)
File "/home/elections/venv/lib/python3.6/site-packages/django/utils/functional.py", line 239, in inner
return func(self._wrapped, *args)
AttributeError: 'User' object has no attribute 'Profile'
It appears to show the issue is with the reference to Gender
data in the current user's profile - an extension of the user model. This is shown here:
class Profile(models.Model):
UserID = models.OneToOneField(User, on_delete=models.CASCADE)
GENDERS = (("M","Male"), ("F","Female"))
Gender = models.CharField(max_length=1, choices=GENDERS)
UserTypeID = models.ForeignKey(UserType, on_delete=models.PROTECT, blank=True, null=True)
EmailConfirmed = models.BooleanField(default=False)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(UserID=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
How do I correctly reference the Gender
attribute of the logged-in user's profile if not the way outlined above?
The reverse accessor of a one-to-one field is always the lower-cased name of the model: so it would be request.user.profile...
.
This would be less surprising to you if you followed standard PEP-8 compliant style and named all your fields with lower case - gender
, voting_open
, email_confirmed
etc. Also note it is not best practice to give relationship fields names ending with ID
as they give access to the whole related object, not just the ID, so your UserID
should be called just user
.
Finally, on gender, please read Falsehoods Programmers believe about Gender and consider whether you really need to ask this information.