В моем приложении Django 2, использующем Django Channels, есть ThreadView
или страница, отображающая поток сообщений между двумя пользователями, с URL-адресом
re_path(r"^(?P<username>[\w.@+-]+)", chat_views.ThreadView.as_view(), name='thread'),
. Внизу страницы есть форма для ввода текста.отправить новое сообщение через request.POST
, которое обрабатывается через ThreadView
.
. Я думаю, что проблема возникает, когда я пытаюсь разместить на странице форму request.POST
delete (DeleteView
) какдля удаления цепочки, URL
path('<int:pk>/delete/', chat_views.ThreadDeleteView.as_view(), name='thread_delete'),
Когда отправляется форма удаления, я получаю сообщение об ошибке
DoesNotExist at /messages/2/delete/ User matching query does not exist.
При цитировании этих строк при возникновении ошибки (из views.py
и models.py
)
self.object = self.get_object()
obj, created = Thread.objects.get_or_new(self.request.user, other_username)
user2 = Klass.objects.get(username=other_username)
Первая строка идет от функции def post
на ThreadView
, и я не уверен, почему это срабатывает.
Тема не удаляется, поскольку, когда я возвращаюсь в папку "Входящие", она все еще там.
Я новичок и, возможно, все неправильно понимаю, поэтому буду благодарен за любые отзывы.
views.py
class InboxView(LoginRequiredMixin, ListView):
template_name = 'chat/inbox.html'
context_object_name = 'threads'
def get_queryset(self):
return Thread.objects.by_user(self.request.user).exclude(chatmessage__isnull=True).order_by('-timestamp')
class ThreadView(LoginRequiredMixin, FormMixin, DetailView):
template_name = 'chat/thread.html'
form_class = ComposeForm
success_url = '#'
def get_queryset(self):
return Thread.objects.by_user(self.request.user)
def get_object(self):
other_username = self.kwargs.get("username")
obj, created = Thread.objects.get_or_new(self.request.user, other_username)
if obj == None:
raise Http404
return obj
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = self.get_form()
return context
def post(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseForbidden()
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
thread = self.get_object()
user = self.request.user
message = form.cleaned_data.get("message")
ChatMessage.objects.create(user=user, thread=thread, message=message)
return super().form_valid(form)
class ThreadDeleteView(DeleteView):
model = Thread
success_url = reverse_lazy('chat:inbox')
models.py
class ThreadManager(models.Manager):
def by_user(self, user):
qlookup = Q(first=user) | Q(second=user)
qlookup2 = Q(first=user) & Q(second=user)
qs = self.get_queryset().filter(qlookup).exclude(qlookup2).distinct()
return qs
# method to grab the thread for the 2 users
def get_or_new(self, user, other_username): # get_or_create
username = user.username
if username == other_username:
print(other_username)
return None, None
# looks based off of either username
qlookup1 = Q(first__username=username) & Q(second__username=other_username)
qlookup2 = Q(first__username=other_username) & Q(second__username=username)
qs = self.get_queryset().filter(qlookup1 | qlookup2).distinct()
if qs.count() == 1:
return qs.first(), False
elif qs.count() > 1:
return qs.order_by('timestamp').first(), False
else:
Klass = user.__class__
user2 = Klass.objects.get(username=other_username)
if user != user2:
obj = self.model(
first=user,
second=user2
)
obj.save()
return obj, True
return None, False
class Thread(models.Model):
first = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='chat_thread_first')
second = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='chat_thread_second')
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
objects = ThreadManager()
def __str__(self):
return f'{self.id}'
@property
def room_group_name(self):
return f'chat_{self.id}'
def broadcast(self, msg=None):
if msg is not None:
broadcast_msg_to_chat(msg, group_name=self.room_group_name, user='admin')
return True
return False
Тема HTML-страницы
<!-- Delete Thread -->
<form action="{% url 'chat:thread_delete' thread.id %}" method='POST'>
{% csrf_token %}
<button type='submit' class='btn btn-light' value='delete'>
<i class="fas fa-trash-alt" style="color:royalblue">
</i>
</button>
</form>
<!-- text input / write message form -->
<form id='form' method='POST'>
{% csrf_token %}
<input type='hidden' id='myUsername' value='{{ user.username }}' />
{{ form.as_p }}
<center><button type="submit" class='btn btn-success disabled' value="Send">Send</button></center>
</form>
urls.py
app_name = 'chat'
urlpatterns = [
path('', chat_views.InboxView.as_view(), name='inbox'),
re_path(r"^(?P<username>[\w.@+-]+)", chat_views.ThreadView.as_view(), name='thread'),
path('<int:pk>/delete/', chat_views.ThreadDeleteView.as_view(), name='thread_delete'),