Search code examples
pythondjangodjango-viewsdjango-urls

getting model object using .get(slug=slug) return an error: Invitation matching query does not exist


I am creating a notification system using django, I'm using django signal to create Notification model when the Invitation model is created, but when I created the Invitation model, and click on the link that are in notification template it says: Invitation matching query does not exist. This is a booking application, we want to send that link to the person who created the Invitation model via his email, so that he can see his information, but the link does not gives the person information when I click it in the notification template it says: DoesNotExist at /invitation_information/OlaRooms-123297186425/ Invitation matching query does not exist.

views.py

def invitation_information(request, slug):
    invitation = Invitation.objects.get(slug=slug)
    return render(request, 'invitations.html', {'invitation':invitation})

urls.py

    path('invitation_information/<slug:slug>/', views.invitation_information, name='invitation_information'),

notification template

<div class="container">
        <div class="row">
            {% for notification in notifications %}
            {% if not notification.is_read %}
            <div class="col-md-3">
                <div class="card">
                    <div class="card-body">
                        <a href="{{ notification.link }}">
                            {{ notification.message }}
                        </a>
                    </div>
                </div>
            </div>
            {% endif %}
            {% endfor %}
        </div>
    </div>

signals:

@receiver(post_save, sender=Invitation)
def notification_signals(sender, instance, created, **kwargs):
    message = f"{instance.first_name} {instance.last_name} booked our {instance.room_type.room_type} room for {instance.number_of_day} day"
    link = reverse('Invitation_Information', args=[str(instance.room_type.slug)])
    room_id_number = generate_random_number()
    notification = Notification.objects.create(
        user=instance.room_type.user, message=message, link=link,
        room_id_number=room_id_number
    )
    notification.save()

My Models:

class Room(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    room_type = models.ForeignKey(RoomType, on_delete=models.CASCADE)
    description = models.TextField()
    image_1 = models.ImageField()
    image_2 = models.ImageField()
    image_3 = models.ImageField()
    image_4 = models.ImageField()

    slug = models.SlugField(unique=True, default=generate_random_number_for_slug)

    def __str__(self):
        return str(self.room_type)

class Invitation(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=150)
    room_type = models.ForeignKey(Room, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)

    slug = models.SlugField(unique=True, default=generate_random_number)

    def __str__(self):
        return str(self.first_name)

class Notification(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    is_read = models.BooleanField(default=False)
    message = models.TextField()
    link = models.URLField()
    room_id_number = models.CharField(max_length=225, unique=True)

How can i solve this problem? so that when i click the link, it will shows the person information, I am using slug instead of id, because using the id: one person can see some people information by typing the number of the id, but using slug, one cannot see other people information.


Solution

  • The problem is with this line:

    link = reverse('Invitation_Information', args=[str(instance.room_type.slug)])
    

    You are generating a link with the slug belonging to the RoomType, as opposed to the invitation. You also need to provide the same case for the reverse lookup. The following should fix it:

    link = reverse('invitation_information', args=[str(instance.slug)])