什么是pythonic&;用Django编写函数的MVC友好方法?
我正在用Django 1.8.4创建一个简单的应用程序,它允许用户共享来自其他网站的链接,并具有向上投票和向下投票功能。有一些可重用的应用程序可以处理这个问题,但我更喜欢编写自己的代码来“学习”Django。但是经过几天的尝试,我想我已经得到了一个相当糟糕的代码。它几乎可以正常工作,但对我来说,它并不是真正的pythonic,而且我认为在Django做事情不是正确的方式 下面是处理投票的代码部分: models.py什么是pythonic&;用Django编写函数的MVC友好方法?,python,django,django-models,django-forms,Python,Django,Django Models,Django Forms,我正在用Django 1.8.4创建一个简单的应用程序,它允许用户共享来自其他网站的链接,并具有向上投票和向下投票功能。有一些可重用的应用程序可以处理这个问题,但我更喜欢编写自己的代码来“学习”Django。但是经过几天的尝试,我想我已经得到了一个相当糟糕的代码。它几乎可以正常工作,但对我来说,它并不是真正的pythonic,而且我认为在Django做事情不是正确的方式 下面是处理投票的代码部分: models.py class Vote(models.Model): UP, DOWN
class Vote(models.Model):
UP, DOWN = range(2)
TYPE_CHOICES = [(UP, "Upvote"), (DOWN, "DownVote")]
voter = models.ForeignKey(User)
link = models.ForeignKey(Link, related_name='votes')
vote_type = models.IntegerField(choices=TYPE_CHOICES, db_index=True)
vote_date = models.DateTimeField(db_index=True, auto_now=True)
然后我将这个模型传递到一个简单的表单,下面是模板代码:
link_detail.html
<form method="POST" action="{% url 'vote' %}" class="vote_form">
{% csrf_token %}
<input type="hidden" id="id_link" name="link" class="hidden_id" value="{{ link.pk }}"/>
<input type="hidden" id="id_link" name="voter" class="hidden_id" value="{{ user.pk }}"/>
<input type="hidden" id="id_link" name="vote_type" class="hidden_id" value="0"/>
<button> + </button>
[up votes: {{ link.up_votes}}]
</form>
<form method="POST" action="{% url 'vote' %}" class="vote_form">
{% csrf_token %}
<input type="hidden" id="id_link" name="link" class="hidden_id" value="{{ link.pk }}"/>
<input type="hidden" id="id_link" name="voter" class="hidden_id" value="{{ user.pk }}"/>
<input type="hidden" id="id_link" name="vote_type" class="hidden_id" value="1"/>
<button> - </button>
[down votes: {{ link.down_votes }}]
</form>
我只是看了一些其他的应用程序,好像对我来说很不错。但这不是我想要的,事实上我不完全理解它是如何工作的
说到所有这些,我的问题是:我想写一些单独的函数,检查用户以前是否被投票过,检查投票的类型,最后使用F()函数将投票应用于模型,并提高用户的声誉。但我不知道这些密码放在哪里?例如,在models.py中,还是编写新经理 只是一些快速观察: 在我看来,似乎您正在将使用表单中的值的代码放置在视图中。那么,为什么不将该逻辑放在表单本身,可能是save()方法中,因为VoteForm应该用于保存/创建/更新投票
def save(self, *args, **kwargs):
kwargs['commit'] = False
vote = super(VoteForm, self).save(*args,**kwargs)
您不需要测试count()>0,因为空QS将返回False。我将逻辑拆分为两个嵌套的if语句,好像vtype不是0,而是1
if v_type == '0':
if up_voted:
<do stuff>
else:
<do downvoted stuff>
else:
if up_voted:
<do stuff>
else:
<do downvoted stuff>
希望其中的一些内容对您进行重构有所帮助
编辑:
您可以使用LinkManager方法代替代码中的Link.objects.filter().update()。它会将其重构给经理。因此,投票权上升
Link.objects.update_up_votes(pk)
或者减少投票权
Link.objects.update_up_votes(pk, increment=False)
请记住,必须通过对象将自定义管理器添加到链接类中
对于您的模板-我没有真正查看它,但是在VoteForm上执行{{form.as_p}}将为您提供所有已格式化的字段。您不需要两个表单,因为它们发布到同一个视图。只要按照你的逻辑来决定。您也不需要访问那里的用户,因为您的投票是通过Vote.voter进行的。实际上它非常有用。但是我对调用LinkManager方法有点困惑。我应该从哪里叫它?例如,从视图(而不是零件)中,是否了解模板中的重复线?
Link.objects.update_up_votes(pk)
Link.objects.update_up_votes(pk, increment=False)