Django Я хочу ограничить голосование пользователей один раз в 24 часа, но я ограничил его для каждой статьи, а не для пользователя - PullRequest
0 голосов
/ 26 апреля 2020

Я бы хотел попросить вас о помощи. Я хотел просто создать систему голосования за вопросы. И у меня получилось, тогда я хотел ограничить голосование пользователей только один раз в 24 часа, и я потерпел неудачу.

Я знаю, чего хочу достичь, но не знаю, как его кодировать.

Прямо сейчас с моей ошибкой я ограничил голосование ВОПРОСОМ один раз в 24 часа. Вместо этого я хотел ограничить одного ПОЛЬЗОВАТЕЛЯ голосовать ОДНАЖДЫ за 24 часа по КАЖДОМУ вопросу. Поэтому я сделал довольно глупую ошибку. Вот мой код с моей ошибкой:

models.py:

class Question(models.Model):
    question = models.CharField(max_length=300)
    answered = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    datecompleted = models.DateTimeField(null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    votesscore = models.IntegerField(default='0')
    votescoresubmitted = models.DateTimeField(null=True, blank=True)
    amountofvotes = models.IntegerField(default='0')

    def __str__(self):
        return self.question

views.py:

@login_required()
def questionvoteup(request, question_pk):
    question = get_object_or_404(Question, pk=question_pk, user=request.user)
    if request.is_ajax() and request.method == "POST":
        if question.votescoresubmitted is None or timezone.now() > question.votescoresubmitted + timedelta(minutes=1440):
            question.votesscore += 1
            question.amountofvotes += 1
            question.votescoresubmitted = timezone.now()
            question.save()
            data = {
                "msg": 'Thank you for your vote!'
            }
            return JsonResponse(data)
        else:
            raise forms.ValidationError("You can vote only one time every 24 hours.")
    else:
        return HttpResponse(400, 'Invalid form')

Прямо сейчас я вижу это ясно. Я думаю, что мне нужно добавить это "voicescoresubmitted" в класс User и сделать его каким-то уникальным для каждого вопроса. Но я не могу придумать, как мне к этому подойти. Я буду очень благодарен за вашу помощь.

Спасибо.


Редактировать:

Я боролся с этим, и я придумал дополнительную модель, которая должна хранить информацию по поводу голосов. Прямо сейчас мой код выглядит следующим образом: models.py:

from django.db import models
from django.contrib.auth.models import User


class Question(models.Model):
    question = models.CharField(max_length=300)
    answered = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    datecompleted = models.DateTimeField(null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.question


class Answer(models.Model):
    question_id = models.ForeignKey(Question, on_delete=models.CASCADE, blank=False, null=True)
    answer = models.TextField(max_length=1000)
    created = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.answer


class VoteQuestion(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    question_id = models.ForeignKey(Question, on_delete=models.CASCADE, blank=False, null=True)
    votesubmitted = models.DateTimeField(null=True, blank=True)
    votesscore = models.IntegerField(default='0')
    amountofvotes = models.IntegerField(default='0')

views.py:

@login_required()
def questionvoteup(request, question_pk):
    votequestion = get_object_or_404(VoteQuestion, pk=question_pk, user=request.user)
    current_time = timezone.now()
    if request.is_ajax() and request.method == "POST":
        if not votequestion.votesubmitted or current_time > votequestion.votesubmitted + timedelta(days=1):
            votequestion.votesscore += 1
            votequestion.amountofvotes += 1
            votequestion.votesubmitted = current_time
            votequestion.save()
            msg = "Thank you for your vote!"
        else:
            msg = "You can vote only one time every 24 hours."
        data = {"msg": msg}
        return JsonResponse(data)
    else:
        return HttpResponse(400, 'Invalid form')

и home. html (где я запускаю голосование UP):

<ul>
    {% for question in allquestionswithanswers %}
    <li>
        {{ question }} Score: {{ VoteQuestion.votesscore }} {{ question.user }}
        <br><br>

        <form class='my-ajax-form' method='POST' action='' data-url="{% url 'questionvoteup' question.id %}" >
        {% csrf_token %}
        <button type='submit'>UP</button>
        </form>



        {% for answer in question.answer_set.all %}
            {{ answer }}<br>
        {% endfor %}
    </li>
    {% endfor %}

</ul>

Тем не менее, после нажатия кнопки «ВВЕРХ» я получаю сообщение об ошибке:

Page not found at /viewquestion/6/voteup
No VoteQuestion matches the given query.

1 Ответ

1 голос
/ 27 апреля 2020

Есть несколько способов сделать это:

  • Записать голоса как независимые объекты, связанные с пользователем, и вопрос
  • Записать историю голосования пользователя как часть объекта этого пользователя.

Первое, что вам нужно сделать, это создать объект голосования со связанными полями user и question (отношение многие-к-одному ForeignKey). Этот способ почти всегда проще сделать.

Второй способ: добавить пользовательское поле в модель пользователя, чтобы отслеживать историю голосования для этого пользователя. См. Расширение пользователя Django по умолчанию

И, возможно, на ваш взгляд вместо ValidationError выведите также сообщение:

@login_required
def questionvoteup(request, question_pk):
    if request.is_ajax() and request.method == "POST":
        current_time = timezone.now()
        votequestion, created = VoteQuestion.objects.get_or_create(question_id=question_pk, user=request.user)
        if not votequestion.votescoresubmitted or current_time > votequestion.votescoresubmitted + timedelta(days=1):
            votequestion.votesscore += 1
            votequestion.amountofvotes += 1
            votequestion.votescoresubmitted = current_time
            votequestion.save()
            msg = "Thank you for your vote!"
        else:
            msg = "You can vote only one time every 24 hours."
        data = {
            "msg": msg
        }
        return JsonResponse(data)
    else:
        return HttpResponse(400, 'Invalid form')

А ваша VoteQuestion модель:

class VoteQuestion(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    votesubmitted = models.DateTimeField(null=True, blank=True)
    votesscore = models.IntegerField(default=0)
    amountofvotes = models.IntegerField(default=0)

    class Meta:
        unique_together = ['user', 'question']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...