Django channel или Django signals, какой из них я должен использовать, чтобы позволить пользователю получать уведомление, когда происходит какое-то действие
Я создал приложение, в котором пользователи могут размещать Вопросы и получать Ответы от некоторых пользователей, как мы делаем это в stackoverflow. Я не хочу, чтобы пользователь обновлял страницу, просто дайте ему знать, что кто-то ответил на его вопрос. Я хочу реализовать функции связи между этими пользователями.
Мои модели
class Question(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100, blank=False, null=False)
body = RichTextField(blank=False, null=False)
category = models.CharField(max_length=50, blank=False, null=False)
def __str__(self):
return str(self.title)
class Answer(models.Model):
user = models.ForeignKey(User, blank=False, null=False, on_delete=models.CASCADE)
answer = RichTextField(blank=False, null=False)
post = models.ForeignKey(Question, blank=False, null=False, on_delete=models.CASCADE)
def __str__(self):
return str(self.user)
Мои взгляды:
class My_Question(LoginRequiredMixin, CreateView):
model = Question
fields = ['title', 'body', 'category']
template_name = 'question.html'
success_url = reverse_lazy('index')
def form_valid(self, form):
form.instance.user = self.request.user
return super (My_Question, self).form_valid(form)
class My_Answer(LoginRequiredMixin, CreateView):
model = Answer
fields = ['answer']
template_name = 'answer.html'
success_url = reverse_lazy('index')
def form_valid(self, form):
form.instance.user = self.request.user
form.instance.post_id = self.kwargs['pk']
return super (My_Answer, self).form_valid(form)
def viewQuestion(request, pk):
question = Question.objects.get(id=pk)
answers = Answer.objects.filter(post_id=question)
context = {'question':question, 'answers':answers}
return render(request, 'viewQuestion.html', context)
Я хочу реализовать функцию Notifications, чтобы когда User отвечает на вопрос, автор этого Question получит уведомление, которое перенаправит его/ее на вопрос, на который кто-то ответил Question, подобно тому, как мы получаем уведомления в stack overflow каждый день на работе.
Я пытаюсь понять каждый из этих методов django channels и django signals, но кажется, что мне нужно больше объяснений и помощи, чтобы внедрить это в мое приложение.
Я пытаюсь реализовать это, используя django signals, поскольку django channels учебники сосредоточены на системе графиков.
я пытаюсь создать новую модель под названием Notification
class Notifications(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
notify = models.ForeignKey(Answer, on_delete=models.CASCADE)
def __str__(self):
return str(self.user)
и сделать в моих представлениях что-то вроде этого:
def notifications(request, pk):
answer = Answer.objects.get(id=pk)
get_notify = Notification.objects.filter(notify=answer)
return render(request, 'notification.html')
Делать что-то вроде этого кажется более простым способом, но проблема в том, что я не знаю, как уведомить пользователя из шаблона, когда происходит какое-то действие. Пожалуйста, как я могу сделать это в django? Большое спасибо.
Вот набросок базовой системы уведомлений в Django:
Модель
Вам нужна модель для хранения уведомлений. Каждое уведомление принадлежит пользователю и имеет содержимое (т.е. текстовое сообщение). Также необходимо хранить информацию о том, было ли сообщение прочитано, и временную метку:
class Notification(models.Model):
is_read = models.BooleanField(default=False)
message = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
Создание уведомления
Затем вы можете создать новое уведомление для пользователя, когда это необходимо, например, когда другой пользователь отвечает на вопрос, вы также можете создать уведомление для владельца вопроса в представлении.
def form_valid(self, form):
...
form.instance.user = self.request.user
question_author = form.instance.post.user
Notification.objects.create(user=question_author, text="New answer!")
...
return super().form_valid(form)
Список уведомлений
Тогда вам нужна страница, на которой будут перечислены все уведомления для текущего пользователя. Это можно реализовать с помощью стандартного представления списка.
Запрос будет выглядеть примерно так:
class NotificationListView(ListView):
model = Notification
def get_queryset(self):
return Notifications.objects.filter(user=self.request.user, order_by="-timestamp")
Вам, конечно, также необходимо определить URL и шаблон для этого нового представления. Мы определим имя URL как notifications.
Показ новых уведомлений пользователям
Наконец, необходимо информировать пользователей о новых уведомлениях. Это можно сделать, проверив, сколько непрочитанных уведомлений у текущего пользователя, и показав значок на веб-значке. Это будет частью представления индекса.
@login_required(login_url='login')
def index(request):
...
unread_notifications = Notification.objects.filter(user=request.user, is_unread=True).count()
context["unread_notifications"] = unread_notifications
...
Затем на главной странице вам нужна ссылка на страницу, которая показывает все уведомления и значок, который показывает, сколько непрочитанных уведомлений у текущего пользователя. Что-то вроде этого:
<a href="{% url "notifications" %}">
Notifications
{% if unread_notifications %}
<span class="badge bg-secondary">{{ unread_notifications }}</span>
{% endif %}
</a>
Пример из реальной жизни
Если вы хотите посмотреть, как это реализовано в реальном проекте, вот ссылка на проект с открытым исходным кодом под названием "Alliance Auth", который реализует веб-страницу портала и имеет очень похожую архитектуру уведомлений. Ссылка на приложение для уведомлений внутри этого портала: https://gitlab.com/allianceauth/allianceauth/-/tree/master/allianceauth/notifications