Chris Marshall
Chris Marshall

Reputation: 39

Trying to pass a foreign key of my model into URL for dynamic routing

I have 3 models, a custom user model (using AbstractUser - User/Brand models) and a Message model:

class User(AbstractUser):
    is_brand = models.BooleanField(default=False)
    is_influencer = models.BooleanField(default=False)

class Brand(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name="brand_info")
    email = models.EmailField()
    brand_name = models.CharField(max_length=100, blank=True)

class Message(models.Model):
    recipient = models.ForeignKey(User, on_delete=models.CASCADE, related_name='recipient')
    sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sender')
    message_content = models.TextField()
    send_time = models.DateTimeField(auto_now_add=True)

I have a view where I want to load up all the messages associated with a particular Brand, and this page will also have the attribute (from Brand model) as a dynamic URL parameter.

Here's my current code for views.py:

def conversation_view(request, username):
    messages = Message.objects.filter(Q(message__sender=username) | Q(message__recipient=username)).order_by('send_time')
    return render(request, "conversation.html", {
        'messages': messages
        })

And here's my urls.py:

urlpatterns = [
    path('conversation/<username>/', views.conversation_view, name='conversation_view')
]

When I try and load up a page with the appropriate conversation/ URL, I get the following error message: invalid literal for int() with base 10: 'username'

I'm not sure why Django is expecting an int() here? Is it because I'm using sender/recipient from Message model in my view, which are both foreign keys?

Upvotes: 1

Views: 392

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476659

You filter on the message__sender, so then it is expecting a User object, or the primary key of a User object.

You can however filter with message__sender__username=username, the same applies for the recepient:

def conversation_view(request, username):
    messages = Message.objects.filter(
        Q(message__sender__username=username) |
        Q(message__recipient__username=username)
    ).order_by('send_time')
    return render(request, "conversation.html", {
        'messages': messages
        })

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Upvotes: 1

Related Questions