Home > Enterprise >  How to select UserProfileInfo of a User with a certain PrimaryKey - Django
How to select UserProfileInfo of a User with a certain PrimaryKey - Django

Time:12-16

I'm using Django. In my function accept_request(), I'm trying to select the profile of a user with a certain PrimaryKey. Here's the function:

def accept_request(request, pk):
    book = Book.objects.get(id=pk)
    print(book.owner.pk)
    user = request.user
    user_email = request.user.email
    owner_profile = UserProfileInfo.objects.get(user=book.owner)
    owner_house_number = owner_profile.house_number
    owner_phone_number = owner_profile.phone_number
    owner_full_name = owner_profile.full_name
    r = UserRents.objects.get(book_id=pk)
    r.status = 1
    r.save()
    subject = "{}, your request to rent the book, \"{}\", has been accepted.".format(user, book)
    body = "You had requested to rent the book, \"{}\". It's been accepted! You can head over to #{} to get the book. You can contact the owner, {}, at  91 {}. Please return the book in the same condition as it was when you got it.\n Hope you enjoy reading the book!".format(book, owner_house_number, owner_full_name, owner_phone_number)
    sender_email = "[email protected]"
    receiver_email = user_email
    password = "Zt2.~[3d*.[Y5&5r"

    # Create a multipart message and set headers
    message = MIMEMultipart()
    message["From"] = sender_email
    message["To"] = receiver_email
    message["Subject"] = subject
    message["Bcc"] = receiver_email  # Recommended for mass emails

    # Add body to email
    message.attach(MIMEText(body, "plain"))

    text = message.as_string()

    # Log in to server using secure context and send email
    context = ssl.create_default_context()
    with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
        server.login(sender_email, password)
        server.sendmail(sender_email, receiver_email, text)
    
    return redirect("/")

This is the UserProfileInfo model in models.py:

class UserProfileInfo(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE)
    full_name = models.CharField(max_length=1000, blank=True)
    house_number = models.CharField(max_length=5, blank=True)
    email = EmailField(max_length=1000, blank=True)
    creation_date = models.DateTimeField(default=timezone.now)
    phone_number = models.CharField(max_length=20, blank=True, null=True)
    def __str__(self):
        return self.user.username

And here's the Book model in models.py:

class Book(models.Model):
    title = models.CharField(max_length=1000, blank=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    description = models.TextField()
    author = models.CharField(max_length=1000, blank=True, null=True)
    thumbnail = models.ImageField(upload_to='book_thumbnails', blank=True)
    creation_date = models.DateTimeField(default=timezone.now)
    status = IntegerField(default=1)
    min_age = models.IntegerField(blank=True, null=True)
    max_age = models.IntegerField(blank=True, null=True)
    def __str__(self):
        return self.title

When I go to the URL I've fixed for this function, it gives an error:

DoesNotExist at /main/accept_rent_request/1/
UserProfileInfo matching query does not exist.

The error's at the line where I try to access the UserProfileInfo of the owner of the book:

owner_profile = UserProfileInfo.objects.get(user=book.owner)

Django is not able to access the profile of the owner. What can I do to fix the issue?

CodePudding user response:

First, you can access the user's profile info by doing

owner_profile = book.owner.userprofileinfo

Also, the error stems from your UserProfileInfo not existing. If you want to explictly query it, you can first check if it exists, then assigning it to owner_profile

user_profile_info_query = UserProfileInfo.objects.filter(user=book.owner)
if user_profile_info_query.exists():
    owner_profile = user_profile_info_query.first()

You can maybe create a new UserProfileInfo in the shell and assign the user to it so you can test.

  • Related