在模型上投票

时间:2018-06-19 23:19:17

标签: django python-3.x

每次对模型进行投票时,我都无法增加其poll_score属性。这是我的模型:

 # idea model
 class Idea(models.Model):
     User = ('accounts.User')
     creator = models.ForeignKey(User, related_name='ideas', on_delete=models.PROTECT)
     title = models.CharField(max_length=100, null=True, blank=True)
     vote_score = models.BigIntegerField(default=0, null=True, blank=True)
     votes = VotableManager()

 #vote model
 class Vote(models.Model):
     user = models.ForeignKey(AUTH_USER_MODEL)
     content_type = models.ForeignKey(ContentType)
     object_id = models.PositiveIntegerField()
     content_object = GenericForeignKey()
     create_at = models.DateTimeField(auto_now_add=True)

     vote = models.NullBooleanField()

     objects = VoteManager()

     class Meta:
         unique_together = ('user', 'content_type', 'object_id')

     @classmethod
     def votes_for(cls, model, instance=None):

         ct = ContentType.objects.get_for_model(model)
         kwargs = {
        "content_type": ct
    }
         if instance is not None:
             kwargs["object_id"] = instance.pk

         return cls.objects.filter(**kwargs)

 #manager
_VotableManager(models.Manager):
     def __init__(self, through, model, instance, field_name='votes', extra_field='vote_score'):
         self.through = through
         self.model = model
         self.instance = instance
         self.field_name = field_name
         self.extra_field = extra_field
         self.name = model.title

     @instance_required
     def up(self, user, vote):
         with transaction.atomic():
             if self.through.objects.filter(user=user, content_object=self.instance).exists():
                 c_type = ContentType.objects.get_for_model(self.instance)
                 vote_obj = self.through.objects.get(user=user, object_id=self.instance.id, content_type=c_type)
                 vote_obj.vote = vote
                 vote_obj.save()
                 self.instance.save()
             else:
                 self.through(user=user, content_object=self.instance, vote=vote).save()
                 if self.extra_field:
                     setattr(self.instance, self.extra_field, F(self.extra_field)+1)
                     self.instance.save()

我的目标是拥有它,因此,在创建想法时,创建者会自动对其计为1票,这样就属于该视图:

 # idea create view
 class IdeaCreateView(LoginRequiredMixin, CreateView):
     model = Idea
     form_class = IdeaCreateForm
     template_name = 'idea_create.html'
     success_url = 'success'

     def dispatch(self, *args, **kwargs):
         self.user = get_object_or_404(User, pk=kwargs['pk'])
         return super(IdeaCreateView, self).dispatch(*args, **kwargs)

     def form_valid(self, form):
         idea = form.save(commit=False)
         idea.creator = self.request.user
         idea.save()
         idea.votes.up(user=idea.creator, vote=True)
         idea.vote_score += 1
         return HttpResponseRedirect('success')

然后允许其他用户对此进行投票,属于这种观点:

 #vote view
 class IdeaVoteView(LoginRequiredMixin, CreateView):
     form_class = VoteForm
     required_fields = ('action',)
     template_name = 'vote_confirm.html'
     success_url = 'success'

     def form_valid(self, form):
         obj = Idea.objects.get(pk=self.kwargs['pk'])
         user = self.request.user
         user_id = self.request.user.pk
         object_id = obj.pk
         content_type_id = 10
         form_class = VoteForm
         self.vote = form.save(commit=False)
         self.vote.user_id = user_id
         self.vote.object_id = object_id
         self.vote.content_type_id = content_type_id
         if obj.votes.exists(user_id):
             return HttpResponseRedirect('failure')
         else:
             self.vote.save()
             obj.votes.up(user_id)
             return HttpResponseRedirect('success')

     def get_object(self, queryset=None):
         obj = Idea.objects.get(pk=self.kwargs['pk'])
         voters = obj.get_voters()
         return voters

为什么不在管理器上设置extra_field属性会解决此问题,并且视图中出了什么问题?

1 个答案:

答案 0 :(得分:0)

哇,好消息...经过几个小时的自我交谈,我终于明白了。我创建了这个模型函数:

 def vote_up(self):
    self.vote_score += 1
    self.save()

问题是我没有在此函数上调用save()方法,所以增量没有得到保存!真的很简单,但我对此不以为然。无论如何,回答这个问题可能会对某人有所帮助。