Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是pythonic&;用Django编写函数的MVC友好方法?_Python_Django_Django Models_Django Forms - Fatal编程技术网

什么是pythonic&;用Django编写函数的MVC友好方法?

什么是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

我正在用Django 1.8.4创建一个简单的应用程序,它允许用户共享来自其他网站的链接,并具有向上投票和向下投票功能。有一些可重用的应用程序可以处理这个问题,但我更喜欢编写自己的代码来“学习”Django。但是经过几天的尝试,我想我已经得到了一个相当糟糕的代码。它几乎可以正常工作,但对我来说,它并不是真正的pythonic,而且我认为在Django做事情不是正确的方式

下面是处理投票的代码部分:

models.py

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)