diff --git a/helpdesk/migrations/0027_auto_20200107_1221.py b/helpdesk/migrations/0027_auto_20200107_1221.py new file mode 100644 index 00000000..dbd50149 --- /dev/null +++ b/helpdesk/migrations/0027_auto_20200107_1221.py @@ -0,0 +1,71 @@ +# Generated by Django 2.2.6 on 2020-01-07 12:21 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('helpdesk', '0026_kbitem_attachments'), + ] + + operations = [ + migrations.AddField( + model_name='kbcategory', + name='queue', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='helpdesk.Queue', verbose_name='Default queue when creating a ticket after viewing this category.'), + ), + migrations.AddField( + model_name='kbitem', + name='downvoted_by', + field=models.ManyToManyField(related_name='downvotes', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='ticket', + name='kbitem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='helpdesk.KBItem', verbose_name='Knowledge base item the user was viewing when they created this ticket.'), + ), + migrations.AlterField( + model_name='followupattachment', + name='filename', + field=models.CharField(blank=True, max_length=1000, verbose_name='Filename'), + ), + migrations.AlterField( + model_name='followupattachment', + name='mime_type', + field=models.CharField(blank=True, max_length=255, verbose_name='MIME Type'), + ), + migrations.AlterField( + model_name='followupattachment', + name='size', + field=models.IntegerField(blank=True, help_text='Size of this file in bytes', verbose_name='Size'), + ), + migrations.AlterField( + model_name='kbiattachment', + name='filename', + field=models.CharField(blank=True, max_length=1000, verbose_name='Filename'), + ), + migrations.AlterField( + model_name='kbiattachment', + name='mime_type', + field=models.CharField(blank=True, max_length=255, verbose_name='MIME Type'), + ), + migrations.AlterField( + model_name='kbiattachment', + name='size', + field=models.IntegerField(blank=True, help_text='Size of this file in bytes', verbose_name='Size'), + ), + migrations.AlterField( + model_name='kbitem', + name='voted_by', + field=models.ManyToManyField(related_name='votes', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='queue', + name='enable_notifications_on_email_events', + field=models.BooleanField(blank=True, default=False, help_text='When an email arrives to either create a ticket or to interact with an existing discussion. Should email notifications be sent ? Note: the new_ticket_cc and updated_ticket_cc work independently of this feature', verbose_name='Notify contacts when email updates arrive'), + ), + ] diff --git a/helpdesk/models.py b/helpdesk/models.py index ec17b3ba..8a200e27 100644 --- a/helpdesk/models.py +++ b/helpdesk/models.py @@ -1243,7 +1243,14 @@ class KBItem(models.Model): An item within the knowledgebase. Very straightforward question/answer style system. """ - voted_by = models.ManyToManyField(settings.AUTH_USER_MODEL) + voted_by = models.ManyToManyField( + settings.AUTH_USER_MODEL, + related_name='votes', + ) + downvoted_by = models.ManyToManyField( + settings.AUTH_USER_MODEL, + related_name='downvotes', + ) category = models.ForeignKey( KBCategory, on_delete=models.CASCADE, diff --git a/helpdesk/views/kb.py b/helpdesk/views/kb.py index 65283c6e..b095ae3f 100644 --- a/helpdesk/views/kb.py +++ b/helpdesk/views/kb.py @@ -46,12 +46,21 @@ def item(request, item): def vote(request, item): item = get_object_or_404(KBItem, pk=item) vote = request.GET.get('vote', None) - if vote in ('up', 'down'): - if request.user not in item.voted_by: - + if vote == 'up': + if not item.voted_by.filter(pk=request.user.pk): item.votes += 1 - if vote == 'up': - item.recommendations += 1 - item.save() - + item.voted_by.add(request.user.pk) + item.recommendations += 1 + if item.downvoted_by.filter(pk=request.user.pk): + item.votes -= 1 + item.downvoted_by.remove(request.user.pk) + if vote == 'down': + if not item.downvoted_by.filter(pk=request.user.pk): + item.votes += 1 + item.downvoted_by.add(request.user.pk) + item.recommendations -= 1 + if item.voted_by.filter(pk=request.user.pk): + item.votes -= 1 + item.voted_by.remove(request.user.pk) + item.save() return HttpResponseRedirect(item.get_absolute_url())