I am a beginner in learning code and am working on making a simple django site where users can click on other users to view their comments (by clicking their profile). However django keeps throwing this error when I run the site.
My urls.py
from django.urls import path
from . import views
urlpatterns = [
path('login/', views.loginPage, name="login"),
path('logout/', views.logoutUser, name="logout"),
path('register/', views.registerPage, name="register"),
path('', views.home, name="home"),
path('room/<str:pk>/', views.room, name="room"),
path('profile/<str:pk>/', views.userProfile, name='user-profile'),
path('create-room/', views.createRoom, name="create-room"),
path('update-room/<str:pk>', views.updateRoom, name="update-room"),
path('delete-room/<str:pk>', views.deleteRoom, name="delete-room"),
path('delete-message/<str:pk>', views.deleteMessage, name="delete-message"),
my template page 1(profile.html)
{% extends 'main.html' %}
{% block content %}
<h1>{{user.username}}</h1>
{% endblock content %}
feed_component.html (feed component on my home page)
<div>
{% for room in rooms %}
<div>
{% if request.user == room.host%}
<a href="{% url 'update-room' room.id%}">Edit</a>
<a href="{% url 'delete-room' room.id %}">Delete</a>
{% endif %}
<a href="{% url 'user-profile' room.host.id %}">@{{room.host.username}}</a>
<h5>{{room.id}} -- <a href="{% url 'room' room.id %}">{{room.name}}</a></h5>
<small>{{room.topic.name}}</small>
<hr>
</div>
{% endfor %}
</div>
views.py
def loginPage(request):
page = 'login'
if request.user.is_authenticated:
return redirect('home')
if request.method == 'POST':
username = request.POST.get('username').lower()
password = request.POST.get('password')
try:
user = User.objects.get(username=username)
except:
messages.error(request, 'User does not exist')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
messages.error(request, 'Username or password does not match')
context = {'page': page}
return render(request, 'base/login_register.html', context)
def logoutUser(request):
logout(request)
return redirect('home')
def registerPage(request):
form = UserCreationForm()
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.username = user.username.lower()
user.save()
login(request, user)
return redirect('home')
else:
messages.error(request, 'An error occured during registration')
return render(request, 'base/login_register.html', {'form': form})
def home(request):
q = request.GET.get('q') if request.GET.get('q') != None else ''
rooms = Room.objects.filter(
Q(topic__name__icontains=q) |
Q(name__icontains=q) |
Q(description__icontains=q)
)
topics = Topic.objects.all()
room_count = rooms.count()
room_messages = Message.objects.filter(Q(room__topic__name__icontains=q))
context = {'rooms': rooms, 'topics' : topics, 'room_count': room_count, 'room_messages':room_messages}
return render(request, 'base/home.html', context)
def room(request,pk):
room = Room.objects.get(id=pk)
room_messages = room.message_set.all()
participants = room.participants.all()
if request.method=='POST':
message = Message.objects.create(
user=request.user,
room=room,
body=request.POST.get('body')
)
room.participants.add(request.user)
return redirect('room', pk=room.id)
context = {'room': room,'room_messages': room_messages, 'participants': participants}
return render(request, 'base/room.html', context)
def userProfile(request, pk):
user = User.objects.get(id=pk)
rooms = user.room_set.all()
context = {'user': user, 'rooms' : rooms}
return render(request, 'base/profile.html', context)
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Topic(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Room(models.Model):
host = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
participants = models.ManyToManyField(User, related_name='participants', blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-updated', '-created']
def __str__(self):
return self.name
class Message(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
body = models.TextField()
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-updated', '-created']
def __str__(self):
return self.body[0:50]
CodePudding user response:
It is because pk
is of int
type not type.str
Simply change your all routes to <int:pk>/
.
Try below code:
Urls.py
urlpatterns = [
path('login/', views.loginPage, name="login"),
path('logout/', views.logoutUser, name="logout"),
path('register/', views.registerPage, name="register"),
path('', views.home, name="home"),
path('room/<int:pk>/', views.room, name="room"),
path('profile/<int:pk>/', views.userProfile, name='user-profile'),
path('create-room/', views.createRoom, name="create-room"),
path('update-room/<int:pk>/', views.updateRoom, name="update-room"),
path('delete-room/<int:pk>/', views.deleteRoom, name="delete-room"),
path('delete-message/<int:pk>/', views.deleteMessage, name="delete-message"),
Note:
Always give/
at the end of every route in path function.
Note:
Function based views are generally written insnake_case
notcamelCase
, so it will better if you change your view name touser_profile
instead of.userProfile
CodePudding user response:
I think the error is happening on this line in feed_component.html:
<a href="{% url 'user-profile' room.host.id %}">@{{room.host.username}}</a>
room.host.id
is resolving to a blank string, which is caused by a room object with a null host field.
The Room
model definition does allow for a null host:
class Room(models.Model):
host = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)