3

我正在开展一个项目,用户可以在其中对书籍收藏进行投票。我的模型如下所示:

class Collection(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=31)

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    collection = models.ForeignKey(Collection)

vote_choices = ((-1,'Bad'),
                (0, 'Not good, Not bad'),
                (1,'Good'))

class Vote(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User, related_name='votes')
    book = models.ForeignKey(Book)
    vote = models.IntegerField(choices=vote_choices)

我需要为用户显示一个视图,他们可以在其中查看给定集合中的所有书籍并立即为这些书籍投票,因为这比遍历每本书进行投票更加用户友好。所以我需要一个表单集,每个表单都是:一本书和它的投票。

最初我认为这是一个使用表单集的好机会(我以前从未使用过它们,但我习惯使用表单、模型表单),但我在如何创建这个表单集时遇到了困难。

我想使用基于通用类的视图,因为理论上,我可以轻松地创建/更新所有投票,但我不知道如何做到这一点。

现在,我在 Collection 模型和 User (from ) 模型之间没有直接关系django.contrib.auth.model,但如果这会让事情变得更容易,我不介意添加一个。我真的不需要一个,因为每个用户都通过投票链接到一本书,每本书都链接到一个集合。

我不确定我应该使用表单集还是只使用常规模型表单。

你会怎么做?提前感谢您的帮助。

4

1 回答 1

0

我建议不要在这种情况下使用 django 表单。还有一些更方便的方法。

第一种方式。使用纯 jQuery

扩展您的图书课程:

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    collection = models.ForeignKey(Collection, related_name='books')

    def get_vote(self, user):
        vote = Vote.objects.filter(book=self, user=user)
        if vote:
            return vote.vote
        else:
            return ''

您的观点(如果您愿意,可以在 CBV 上重写):

def list_collection(request, collection_id):
    collection = Collection.objects.get(pk=id)
    user = request.user
    books = []
    for item in collection.books.all():
        book = {
            'id': item.pk,
            'name': item.name,
            'vote': item.get_vote(user)
        }       
        books.append(book)
    return render_to_response('colleciton.html', {'books': books})

def set_vote(request):
    id = request.GET('id')
    vote = int(request.GET('vote'))
    user = request.user
    book = Book.objects.get(pk=id)
    vote = Vote()
    vote.user = user
    vote.vote = vote
    vote.book = book
    vote.save()
    return HttpResponse()

您的网址:

url(r'^list-collection/', 'list_collection', name='list_collection'),
url(r'^set-vote/', 'set_vote', name='set_vote'),

你的 Django 模板:

{% extends 'base.html' %}
{% block content %}
    {% for book in collection.books.all %}
        <div class="book" data-id="{{ book.id }}">
            <div class="book-name">{{ book.name]}</div>
            <div class="book-vote" {% if not book.get_vote %}style="display:none"{% endif %}>book.get_vote</div>
            <div class="voting" {% if book.get_vote %}style="display:none"{% endif %}>
                <button class="vote-up"></button>
                <button class="vote-down"></button>
            </div>
        </div>
    {% endfor %}
{% endblock %}

而javascript就像

$(document).ready(function(){
    $('.vote-up, .vote-down').on('click', function(e){
            var id, vote, t, book_el;
            e.preventDefault();
            t = $(e.currentTarget);
            book_el = t.parents().parents()
            id = book_el.attr('data-id');
            if t.hasClass('vote-up'){
                vote = 1;
            } else {
                vote = -1;
            }
            book_el.find('.book-vote').show();
            book_el.find('.book-vote').text(vote);
            book_el.find('voting').hide();
            $.get("/set-vote", {vote: vote, id: id});
        }); 
});

第二种方式。使用像 Backbone.js 这样的 JavaScript 框架

它使整个过程变得更加容易。特别是如果您打算向您的应用程序添加一些其他功能。另一方面,Backbone 需要一些时间来学习它。

阅读文档查看教程应用程序 TodoMVC其他教程。也许您会发现它更适合您的任务。

于 2013-09-06T14:38:03.477 回答