0

I have a small Django project that consists of 2 models (Event, mem_ev) plus auth User and Profile such that Users --< mem_ev >-- Events (ie a classic many to many relationship between Users & Events).

I want to be able to list all events for a member and all members for an event both of which entail a join between the main dataset and mem_ev.

I have the list of events attended by a member working fine (list_member_events) but cannot get a list of members attending an event (list_event_members) working.

My models.py is:

from django.db import models
from django.utils.text import slugify
from django.contrib.auth.models import User

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE) # Delete profile when user is deleted
    event_count = models.IntegerField(default=0)

    def __str__(self):
        return f'{self.user.username} Profile' #show how we want it to be displayed

class Event(models.Model):
    title = models.CharField(max_length=50)
    slug = models.SlugField(max_length=50,default="", null=False)
    description = models.TextField()
    cost = models.DecimalField(max_digits = 5, decimal_places = 2, default = 0.0)
    event_date = models.DateTimeField(null=True,blank=True)
    attendees = models.IntegerField(default=0)

    class Meta:
        ordering = ['event_date']

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(Event, self).save(*args, **kwargs)

    class Meta:
        ordering = ['event_date']

    def __str__(self):
        return self.title

class mem_ev(models.Model):
    member_id = models.ForeignKey("Profile",on_delete=models.CASCADE)
    event_id = models.ForeignKey("Event",on_delete=models.CASCADE)
    amt_paid = models.DecimalField(max_digits = 5, decimal_places = 2, default = 0.0)
    date_paid = models.DateTimeField(null=True,blank=True)

My views.py is:

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.contrib.auth import authenticate, login
from .models import Event, mem_ev, Profile
from .forms import UserRegistrationForm
from django.contrib.auth.decorators import login_required
from django.contrib.auth import get_user_model

...

def list_event_members(request,id):
    User = get_user_model()
    event_members = User.objects.filter(mem_ev__event_id=id)
    return render(request,'wf/list_event_members.html',{'event_members':event_members})

@login_required
def list_member_events(request,id,username):
    member_events = Event.objects.filter(mem_ev__member_id=id)
    user = User.objects.get(username=username)
    return render(request,'wf/list_member_events.html',{'member_events':member_events,'member':user})

The error I'm getting back is:

FieldError at /list_event_members/8/

Cannot resolve keyword 'mem_ev' into field. Choices are: date_joined, email, first_name, groups, id, is_active, is_staff, is_superuser, last_login, last_name, logentry, password, profile, user_permissions, username

/home/dconran/django/mysite/wf/views.py, line 33, in list_event_members

        event_members = User.objects.filter(mem_ev__event_id=id)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

Clearly it doesn't like the mem_ev bit of the filter but why when it is quite happy with that for list_member_events?

And how do I fix it?

1 Answer 1

1

You are working with profile, not User, so:

event_members = User.objects.filter(profile__mem_ev__event_id=id)
Sign up to request clarification or add additional context in comments.

3 Comments

Thank tou, that has worked like a dream - but I don't understand why. I know that mem_ev__event_id does (or should do) a left join between User and mem_ev and that User has a one-to-one relationship with Profile but your answer suggests (to me) that we are doing a left join on a left join onto mem_ev - or does the first part (profile) imply an inner join?
@DougConrad: you are filtering User objects (User.objects.filter(..)). So you can not use mem_env, since that is not a field for User (not a relation in reverse). So you need to filter the corresponding Profile, so one uses filter__, so the "event_id of the mem_ev of the profile").
willeM - many thanks for this clarification. I think I understand, now. In the mem_ev model I declare member_id as a ForeignKey of Profile whereas in the views.py for list_event_members I'm getting back User objects (ie not Profile objects) so then have to join through Profile then through User to get to the mem_ev record. Thank you for (I think :) increasing my knowledge - Doug

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.