-1

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 Genderdata 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?

cbuch1800
  • 923
  • 3
  • 11
  • 26
  • What is Election and how does it relate to Profile? – Daniel Roseman Mar 02 '18 at 09:42
  • @DanielRoseman `Election` is a model which also has a field called `Gender`. I want to make sure that the election models returned have the same gender value as the user's profile. I have edited the question to explain this better. – cbuch1800 Mar 02 '18 at 09:53

1 Answers1

1

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.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thank you very much for this advice. The solution has worked and I will definitely use clearer convention as you have stated in future. – cbuch1800 Mar 02 '18 at 10:37