const button = document.getElementById('roomJoin');
button.addEventListener('click', function() {
console.log(url = `messenger/${document.getElementById('roomInput').value}`;
window.location = url;);
});
No. Like this.
const button = document.getElementById('roomJoin');
button.addEventListener('click', function() {
url = `messenger/${document.getElementById('roomInput').value}`;
window.location = url;
});
And this should work? Do you need to see my messenger.html file?
Just try it and show us if anything doesn’t work.
If you type chat name correctly in the input, it should work.
Currently, no.
Can I ask, what is this project about? Like, personal? Professional? Fun? School, uni?
personal project. The chat server is the second feature to my django project. The haystack search engine feature is finished, so I’m getting started on the message part of my website.
However, the search engine is about ready for production. So could be professional
It’s an application that centers on the industry of professional tree services/arboriculture.
The search engine allows homeowner end-users to find arborists in nearby areas. The chat server is for arborists to network with property managers/businesses that depend on their commercial services.
So I added the js script to index.html, not sure if I put it in the right place, but here is my modified index.html file
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>ArborHub messenger</title>
<link rel="icon" href="{% static 'favicon.ico' %}">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
<style>
#arboristRoomSelect {
height: 300px;
}
</style>
</head>
<body>
<script>
const button = document.getElementById('roomJoin');
button.addEventListener('click', function() {
url = `messenger/${document.getElementById('roomInput').value}`;
window.location = url;
});
</script>
<div class="container mt-3 p-5">
<div class="row">
<div class="col-12 col-md-8">
<div class="mb-2">
<label for="roomInput">Choose which messenger channel to join:</label>
<input type="text" class="form-control" id="roomInput" placeholder="Messenger channel name">
<small id="roomInputHelp" class="form-text text-muted">You can create a new channel, if one hasn't been already created</small>
</div>
<button type="button" id="roomJoin" class="btn btn-success">Join</button>
</div>
<div class="col-12 col-md-4">
<label for="roomSelect">Current channels</label>
<select multiple class="form-control" id="roomSelect">
{% for channel in channels %}
<option>{{ channel }}</option>
{% endfor %}
</select>
</div>
</div>
</div> <!-- Make sure this closes the outer container -->
</body>
</html>
The button isn’t working, probably because I placed the script in the incorrect place in the file
Move it to the bottom.
index.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>ArborHub messenger</title>
<link rel="icon" href="{% static 'favicon.ico' %}">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
<style>
#arboristRoomSelect {
height: 300px;
}
</style>
</head>
<body>
<div class="container mt-3 p-5">
<div class="row">
<div class="col-12 col-md-8">
<div class="mb-2">
<label for="roomInput">Choose which messenger channel to join:</label>
<input type="text" class="form-control" id="roomInput" placeholder="Messenger channel name">
<small id="roomInputHelp" class="form-text text-muted">You can create a new channel, if one hasn't been already created</small>
</div>
<button type="button" id="roomJoin" class="btn btn-success">Join</button>
</div>
<div class="col-12 col-md-4">
<label for="roomSelect">Current channels</label>
<select multiple class="form-control" id="roomSelect">
{% for channel in channels %}
<option>{{ channel }}</option>
{% endfor %}
</select>
</div>
</div>
</div> <!-- Make sure this closes the outer container -->
</body>
<script>
const button = document.getElementById('roomJoin');
button.addEventListener('click', function() {
url = `messenger/${document.getElementById('roomInput').value}`;
window.location = url;
});
</script>
</html>
Yes. It should work now.
Okay so I tried this, and when I click on ‘Join’ it redirects me to another page. However I get a FieldError error page.
Here is the traceback
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8080/arborchat/messenger/chat/
Django Version: 5.1.8
Python Version: 3.12.7
Installed Applications:
['daphne',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.gis',
'rest_framework',
'haystack',
'django_extensions',
'corsheaders',
'rest_framework_simplejwt',
'django_rest_passwordreset',
'django_celery_results',
'djcelery_email',
'channels',
'arborfindr',
'arborchat']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "/home/corey-james/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 42, in inner
response = await get_response(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 253, in _get_response_async
response = await wrapped_callback(
File "/usr/lib/python3.12/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/Arborhub/MyProject/arborchat/views.py", line 51, in room_view
room, created = Room.objects.get_or_create(name=room_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/query.py", line 948, in get_or_create
return self.get(**kwargs), False
^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/query.py", line 635, in get
clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/query.py", line 1476, in filter
return self._filter_or_exclude(False, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/query.py", line 1494, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/query.py", line 1501, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/sql/query.py", line 1609, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/sql/query.py", line 1641, in _add_q
child_clause, needed_inner = self.build_filter(
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/sql/query.py", line 1491, in build_filter
lookups, parts, reffed_expression = self.solve_lookup_type(arg, summarize)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/sql/query.py", line 1303, in solve_lookup_type
_, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/db/models/sql/query.py", line 1768, in names_to_path
raise FieldError(
^
Exception Type: FieldError at /arborchat/messenger/chat/
Exception Value: Cannot resolve keyword 'name' into field. Choices are: id, online, room_name
Maybe has something to do with my settings?
Error is in room_view function.
Okay here is views
from django.shortcuts import render
from django.shortcuts import render
from arborchat.models import Room, Arborist
from arborfindr.models import User
from rest_framework.views import APIView
from rest_framework.decorators import authentication_classes, permission_classes
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, DjangoModelPermissionsOrAnonReadOnly, AllowAny
from django.contrib.auth import login
from .serializers import RoomSerializer, RegisterChatSerializer, LoginChatSerializer, ArboristProfileSerializer, CompanyProfileSerializer
from rest_framework.authtoken.models import Token
from rest_framework import status, generics, permissions
from rest_framework_simplejwt.tokens import RefreshToken
from drf_haystack.viewsets import HaystackViewSet
from haystack.query import SearchQuerySet
def arborchat_home(request):
return render(request, 'arborchat/index.html', {
'channels': Room.objects.values_list('room_name', flat=True)
})
def index(request):
return render(request, 'arborchat/index.html', {
'rooms': Room.objects.all(),
})
def messenger_room(request, room_name):
room = Room.objects.first()
return render(request, 'messenger.html', {'room': room })
@authentication_classes([JWTAuthentication])
def room_view(request, room_name):
room, created = Room.objects.get_or_create(name=room_name)
return render(request, 'messenger.html', {'room': room})
# API endpoint for Arborist login
@authentication_classes([JWTAuthentication])
class ChatLoginView(APIView):
authentication_classes = (JWTAuthentication,) # Keep as tuple if you prefer
def post(self, request, *args, **kwargs):
serializer = LoginChatSerializer(data=request.data, context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
login(request, user) # Corrected: Pass the request object
token = Token.objects.create(user=user) # Auth Token
if user is not None: # This block is now reachable
# Generate token
refresh = RefreshToken.for_user(user)
access_token = str(refresh.access_token)
return Response({
'message': 'Successful login',
'access_token': access_token,
'refresh_token': str(refresh),
"Token": token.key # Added auth token
}, status=status.HTTP_200_OK)
return Response({'error': 'Invalid email/password'}, status=status.HTTP_401_UNAUTHORIZED) # Now reachable
@authentication_classes([JWTAuthentication])
class ChatRegisterView(generics.CreateAPIView):
queryset = User.objects.all()
serializer_class = RegisterChatSerializer
permission_classes = [permissions.AllowAny]
def post(self, request):
serializer = RegisterChatSerializer(data=request.data, context={'request': request})
if serializer.is_valid():
serializer.save()
return Response({
'message': 'successfully registered', }, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class ArboristProfileView(APIView):
permission_classes = [IsAuthenticated]
authentication_classes = [JWTAuthentication]
serializer_class = ArboristProfileSerializer
def get(self, request):
user = request.user
serializer = self.serializer_class(user)
return Response(serializer.data)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
class CompanyProfileView(APIView):
permission_classes = [IsAuthenticated]
authentication_classes = [JWTAuthentication]
serializer_class = CompanyProfileSerializer
def get(self, request):
user = request.user
serializer = self.serializer_class(user)
return Response(serializer.data)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
class SearchBarView(APIView):
model = Arborist
permission_classes = [IsAuthenticated]
serializer_classes = ArboristProfileSerializer
success_url = '/'
context_object_name = 'all_search_results'
def get(self):
query = self.request.GET.get('search')
results = SearchQuerySet().filter(content=query)
# serialize results based on models
serialized_results = []
for result in results:
if result.model == 'arborist':
serializer = ArboristProfileSerializer(result.object)
elif result.model == 'company':
serializer = CompanyProfileSerializer(result.object)
else:
continue
serialized_results.append(serializer.data)
return Response(serialized_results)
Change this to
@authentication_classes([JWTAuthentication])
def room_view(request, room_name):
room, created = Room.objects.get_or_create(room_name=room_name)
return render(request, 'messenger.html', {'room': room})
.
And see if error changes.
Okay, now it just shows one minor issue, something to with a positional argument
Here is the traceback
@authentication_classes([JWTAuthentication])Environment:
Request Method: GET
Request URL: http://127.0.0.1:8080/arborchat/messenger/
Django Version: 5.1.8
Python Version: 3.12.7
Installed Applications:
['daphne',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.gis',
'rest_framework',
'haystack',
'django_extensions',
'corsheaders',
'rest_framework_simplejwt',
'django_rest_passwordreset',
'django_celery_results',
'djcelery_email',
'channels',
'arborfindr',
'arborchat']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "/home/corey-james/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 42, in inner
response = await get_response(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 253, in _get_response_async
response = await wrapped_callback(
File "/usr/lib/python3.12/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exception Type: TypeError at /arborchat/messenger/
Exception Value: messenger_room() missing 1 required positional argument: 'room_name'
I think it’s referring to this particular view
def messenger_room(request, room_name):
room = Room.objects.first()
return render(request, 'messenger.html', {'room': room })
Problem is here.
Change it to
def messenger_room(request):
room = Room.objects.first()
return render(request, 'messenger.html', {'room': room })
.
Ah I see, it was expecting an argument since I added an extra parameter. I’ll try it now
Okay now it’s saying that the template, messenger.html, doesn’t exist
Here is another traceback
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8080/arborchat/messenger/chat/
Django Version: 5.1.8
Python Version: 3.12.7
Installed Applications:
['daphne',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.gis',
'rest_framework',
'haystack',
'django_extensions',
'corsheaders',
'rest_framework_simplejwt',
'django_rest_passwordreset',
'django_celery_results',
'djcelery_email',
'channels',
'arborfindr',
'arborchat']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Template loader postmortem
Django tried loading these templates, in this order:
Using engine django:
* django.template.loaders.filesystem.Loader: /home/corey-james/Arborhub/MyProject/templates/messenger.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /home/corey-james/venv/lib/python3.12/site-packages/django/contrib/admin/templates/messenger.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /home/corey-james/venv/lib/python3.12/site-packages/django/contrib/auth/templates/messenger.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /home/corey-james/venv/lib/python3.12/site-packages/django/contrib/gis/templates/messenger.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /home/corey-james/venv/lib/python3.12/site-packages/rest_framework/templates/messenger.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /home/corey-james/venv/lib/python3.12/site-packages/haystack/templates/messenger.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /home/corey-james/venv/lib/python3.12/site-packages/django_extensions/templates/messenger.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /home/corey-james/Arborhub/MyProject/arborfindr/templates/messenger.html (Source does not exist)
* django.template.loaders.app_directories.Loader: /home/corey-james/Arborhub/MyProject/arborchat/templates/messenger.html (Source does not exist)
Traceback (most recent call last):
File "/home/corey-james/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 42, in inner
response = await get_response(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 253, in _get_response_async
response = await wrapped_callback(
File "/usr/lib/python3.12/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/Arborhub/MyProject/arborchat/views.py", line 52, in room_view
return render(request, 'messenger.html', {'room': room})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/shortcuts.py", line 25, in render
content = loader.render_to_string(template_name, context, request, using=using)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/template/loader.py", line 61, in render_to_string
template = get_template(template_name, using=using)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/corey-james/venv/lib/python3.12/site-packages/django/template/loader.py", line 19, in get_template
raise TemplateDoesNotExist(template_name, chain=chain)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exception Type: TemplateDoesNotExist at /arborchat/messenger/chat/
Exception Value: messenger.html
Does it exist? Give the correct path bro.