Reputation: 2165
I want to limit the access to detailView of a chatroom to the owner and participants of the room(joiners)
model:
class PublicChatRoom(models.Model):
title = models.CharField(max_length=100, unique=True, blank=False)
owner = models.ForeignKey(User,related_name='chatrooms_created',on_delete=models.CASCADE)
joiners = models.ManyToManyField(User, blank=True,related_name='chatrooms_joined')
view:
class JoinerRoomDetailView(DetailView):
model = PublicChatRoom
template_name = 'detail.html'
def get_queryset(self):
return PublicChatRoom.objects.filter(Q(joiners__in=[self.request.user]) | Q(owner=self.request.user))
and some rooms give the following error :
get() returned more than one PublicChatRoom -- it returned 2!
if I use the view like this:
class JoinerRoomDetailView(DetailView):
model = PublicChatRoom
template_name = 'detail.html'
def get_queryset(self):
return PublicChatRoom.objects.filter(Q(joiners__in=[self.request.user])) #the modified part
only if the user that is in participant list have access, which is correct
and if it's that:
class JoinerRoomDetailView(DetailView):
model = PublicChatRoom
template_name = 'detail.html'
def get_queryset(self):
return PublicChatRoom.objects.filter(Q(owner=self.request.user)) #the modified part
only the creator of room can see it, again correct everything works as expected.
but the Goal is to access rooms that a user own or a part of both, so how can I do that?
Upvotes: 0
Views: 34
Reputation: 3103
Because you have an "OR" clause that will both return a record, you need to make sure you return "distinct" records
class JoinerRoomDetailView(DetailView):
model = PublicChatRoom
template_name = 'detail.html'
def get_queryset(self):
return PublicChatRoom.objects.filter(Q(joiners__in=[self.request.user]) | Q(owner=self.request.user)).distinct()
Upvotes: 1