schrodingerscatcuriosity
schrodingerscatcuriosity

Reputation: 1860

Access a model through a link filterd model

I have three models Person, User and Profile. Profile links a person to a user like this:

class Profile(models.Model):
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE
    )
    person = models.OneToOneField(
        Person,
        on_delete=models.CASCADE
    )

In my person detail view I want to get the username through the person selected.

class PersonDetailView(DetailView):
    model = Person
    template_name = 'people/person_detail.html'

    def get_context_data(self, **kwargs):
        context = super(PersonDetailView, self).get_context_data(**kwargs)
        profile = Profile.objects.filter(person_id=Person.objects.get(pk=self.kwargs['pk']))

        # this line is the problem I guess
        user = User.objects.get(pk=profile.user.user_id)

        context['user_person'] = user
        return context

With this code I get the error

'QuerySet' object has no attribute 'user'

Maybe it is a silly question but I'm lost on this. How do I get the user from The profile filtered from a person?

Thanks in advance, I hope I made mydelf clear enough.

EDIT

I got everything workin with Robert Townley answers, thank you.

Upvotes: 0

Views: 35

Answers (4)

Sergey Melnikov
Sergey Melnikov

Reputation: 11

Looks like you need this:

class PersonDetailView(DetailView):
    model = Person
    template_name = 'people/person_detail.html'

def get_context_data(self, **kwargs):
    user = self.object.profile.user if hasattr(self.object, 'profile') else None
    return super(PersonDetailView, self).get_context_data(user_person=user, **kwargs)

Upvotes: 0

user8060120
user8060120

Reputation:

As i can see, You can use simple soulution for your logic,

class PersonDetailView(DetailView):
    model = Person
    template_name = 'people/person_detail.html'

    def get_context_data(self, **kwargs):
        context = super(PersonDetailView, self).get_context_data(**kwargs)
        context['user_person'] = self.request.user
        # Just only one action
        return context

Upvotes: 0

sumpen
sumpen

Reputation: 541

Correct me if I'm wrong, but it looks like you are creating a relation table to connect a Person with a User.

You do not have to create relation tables in django.

Instead you should add a foreignkey https://docs.djangoproject.com/en/1.11/ref/models/fields/#module-django.db.models.fields.related

Upvotes: 0

Robert Townley
Robert Townley

Reputation: 3564

The line that says:

profile = Profile.objects.filter(person_id=Person.objects.get(pk=self.kwargs['pk']))

should instead grab the Profile from the queryset:

profile = Profile.objects.get(person_id=Person.objects.get(pk=self.kwargs['pk']))

If you do "filter()" you'll receive a queryset. If you do "get()" you'll receive the only object matching that queryset. You can also do:

profile_queryset = Profile.objects.filter(person_id=Person.objects.get(pk=self.kwargs['pk']))
profile = profile_queryset.first()

Note: Only do this if you're sure that the Profile object exists, or you'll get a DoesNotExist error.

Upvotes: 1

Related Questions