Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Django: accessing the related_name on a Model returns None

models.py

from django.contrib.auth.models import AbstractUser
from django.db import models


class User(AbstractUser):
    pass

class Likes(models.Model):
    pass

class Unlikes(models.Model):
    pass

class Post(models.Model):
    post_text = models.TextField(max_length=1000)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    likes = models.ManyToManyField(User, null=True, related_name="liked_posts")
    unlikes = models.ManyToManyField(User, null=True, related_name="unliked_posts")

    def __str__(self):
        return f'{self.user} at {self.created_at}: {self.post_text[0:20]}...'

views.py

def profile(request, username):
    print(User.objects.get(username=username).posts)
    print(Post.objects.filter(user = User.objects.get(username=username)))
    return render(request, 'network/profile.html', {
        'user': request.user,
        'profile': User.objects.get(username=username)
    })

My models.py file defines the relationship between User and post as follows:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')

Running:

print(User.objects.get(username=username).posts)
print(Post.objects.filter(user = User.objects.get(username=username)))

returns:

network.Post.None
<QuerySet [<Post: Joe at 2022-12-18 10:48:18.941880+00:00: test1...>, <Post: Joe at 2022-12-18 10:53:27.407349+00:00: test1...>, <Post: Joe at 2022-12-18 10:53:34.167508+00:00: test2...>]>

My question:
How can the first print statement return no rows, when the second statement returns the expected value (3 rows)? As far as I understand, the two statements should achieve the same thing?

>Solution :

.posts is a Manager, not a QuerySet, you can use .all() [Django-doc], to turn it into a QuerySet:

from django.contrib.auth.decorators import login_required


@login_required
def profile(request, username):
    print(User.objects.get(username=username).posts.all())
    print(Post.objects.filter(user=User.objects.get(username=username)))
    return render(
        request,
        'network/profile.html',
        {'user': request.user, 'profile': User.objects.get(username=username)},
    )

Note: You can limit views to a view to authenticated users with the
@login_required decorator [Django-doc].

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading