Rez
Rez

Reputation: 196

How can I pass in multiple parameters in my Url

So I'm a developer noobie, and building my first project from scratch. I'm currently building a messaging system for my app. How it's supposed to work is that A user goes to a link that checks their current conversations, so conversations are displayed. Then FROM the conversations, there is a link that takes them to a page that displays the contents of that conversation. But I'm having a problem here, because when I try to get the other user's pk to display their messages, my code is instead getting request.user pk and getting ALL the messages that the current user has going on not exclusively between 2 users within that specific conversation. Now, when I manually, and by manually I mean typing the actual pk of the specific user I want to check on that has messages with my user, when I manually enter their pk number in the http, I am able to get the correct messages and exclusive messages. Currently, my href link is passing conversation.pk and I haven't figured out how to get the other users pk. Everything I have tried has kept passing my request.user pk. So I guess what I'm asking is how can I get the other users pk passed in with my url? I am assuming I need to keep conversation.pk, and add the other users pk as another parameter. Or, is there another way to do this? Perhaps putting some extra logic in my view? Or in the template? I'm rather stuck here.

views.py/ message and messages

#displays active conversations
def messages(request,profile_id):


    conversations = Conversation.objects.filter(
        members= request.user
    ).annotate(
        last_message=Max('instantmessage__date')
    ).prefetch_related('members').order_by(
        '-last_message'
    )


#displays contents of conversations, messages 
def message(request, profile_id):


    receiver = get_object_or_404(Profile,id=profile_id)

    exclusive_conversations = Conversation.objects.filter(members= request.user ).filter(members= receiver)


    messages = InstantMessage.objects.filter(receiver__in=exclusive_conversations)


    context = {'messages' : messages, }

    return render(request, 'dating_app/message.html', context)

urls.py/message, messages

path('message/<int:profile_id>/', views.message, name='message'),
    path('messages/<int:profile_id>/', views.messages, name='messages'),
]

messages.html

{% for conversation in conversations%}
    <li class="text-right list-group-item">
        {% for member in conversation.members.all %}{% if member != user %}
            {{ member.username }}
            <a href="{% url 'dating_app:message' conversation.pk %}">Start messaging </a>
            <br><br>
        {% endif %}{% endfor %}

    </li>
{%endfor %}

message.html

{% for message in messages %}

        {% if message.sender_id == request.user.id  %}
        <li class="text-right list-group-item"> {{ message.message }}<br>{{ message.date }} </li>
        {% else %}
        <li class="text-left list-group-item"> {{ message.message }}<br>{{ message.date }} </li>

        {% endif %}



{%endfor %}

**models.py **

class ProfileManager(BaseUserManager):



    def create_user(self, username, email,description,photo, password=None):
        if not email:
            raise ValueError("You must creat an email")
        if not username:
            raise ValueError("You must create a username!")
        if not description:
            raise ValueError("You must write a description")
        if not photo:
            raise ValueError("You must upload a photo")

        user = self.model(
                email=self.normalize_email(email),
                username = username, 
                description= description,
                photo= photo,

            )

        user.set_password(password)
        user.save(using=self._db)
        return user 


    def create_superuser(self, username, email,description,photo, password):
        user = self.create_user(
                email=self.normalize_email(email),
                password=password,
                username=username,
                description=description,
                photo=photo,

            )

        user.is_admin=True
        user.is_staff=True
        user.is_superuser=True
        user.save(using=self._db)
        return user




class Profile(AbstractBaseUser):

    class Meta:
        swappable = 'AUTH_USER_MODEL'


    email                       = models.EmailField(verbose_name="email")
    username                    = models.CharField(max_length=30, unique=True)
    date_joined                 = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
    last_login                  = models.DateTimeField(verbose_name='last login', auto_now=True)
    is_admin                    = models.BooleanField(default=False)
    is_active                   = models.BooleanField(default=True)
    is_staff                    = models.BooleanField(default=False)
    is_superuser                = models.BooleanField(default=False)
    #what I added
    description                 = models.TextField()
    photo                       = models.ImageField(upload_to='profile_photo',blank=False, height_field=None, width_field=None, max_length=100)
    matches                     = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='+', blank=True)



    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['description','photo','email']


    objects = ProfileManager()


    def __str__(self):
        return self.username


    def has_perm(self, perm, obj=None):
        return self.is_admin


    def has_module_perms(self,app_label):
        return True



class UserVote(models.Model):

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    voter = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='given_vote', on_delete=models.CASCADE)
    vote = models.BooleanField(default=False)

    class Meta:
        unique_together = (('user', 'voter'))


class Conversation(models.Model):
    members = models.ManyToManyField(settings.AUTH_USER_MODEL)




class InstantMessage(models.Model):

    sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name= 'senderr',on_delete=models.CASCADE )
    receiver = models.ForeignKey(Conversation, on_delete=models.CASCADE)
    message = models.TextField()
    date = models.DateTimeField(auto_now_add=True)


    def __unicode__(self):
        return self.message

    #tests to see if messages are exclusive between sender, receiver 
    @classmethod
    def find_messages_exclusive_to_profile(cls,sender,receiver):
        #members = receiver AND sender, not receiver or sender 
        exclusive_conversations = Conversation.objects.filter(members= receiver ).filter(members= sender)


        exclusive_messages = InstantMessage.objects.filter(receiver__in=exclusive_conversations)

        return exclusive_messages

Upvotes: 1

Views: 172

Answers (1)

Rez
Rez

Reputation: 196

Ok I ended up figuring out my own problem. Ok, so what I was doing wrong was passing the Conversation.pk rather than the other users pk. By passing in the conversation pk, I wasn't able to exclusively filter through only messages between the two users, but I was getting messages that weren't exclusive between the two users. And, the conversation PK will always have fewer pk's than users. There may be 3 conversation objects, but 5 users with differing pk's. Anyhow, the solution was simply to change conversation.pk to member.pk like so in messages.html

{% for conversation in conversations%}
<li class="text-right list-group-item">
    {% for member in conversation.members.all %}{% if member != user %}
        {{ member.username }}
        <a href="{% url 'dating_app:messages' member.pk %}">Start messaging </a>
        <br><br>
    {% endif %}{% endfor %}

</li>
{%endfor %}

And then, I tweaked my message.html to filter between request.user and other_user

{% for message in messages %}



        {% if message.sender_id == request.user.id %}
        <li class="text-right list-group-item"> {{ message.message }}<br>{{ message.date }} </li>
        {% elif message.sender_id == profile.id %}
        <li class="text-left list-group-item"> {{ message.message }}<br>{{ message.date }} </li>

        {% endif %}



{%endfor %}

Upvotes: 1

Related Questions