根据另一个模型对象的列表从模型中获取数据

时间:2018-08-02 13:30:55

标签: python django python-3.x django-models

我有以下两种模型:

class Books(models.Model):
    poster = models.CharField(max_length=2000)
    bookid = models.CharField(max_length=10)
    title = models.CharField(max_length=150)
    year = models.IntegerField()

    def __str__(self):
        return self.title



class UserRating(models.Model):
    userid = models.CharField(max_length=20)
    rating = models.CharField(max_length=5)
    bookid = models.CharField(max_length=10)

views.py中,我获得所有当前登录的用户费率并将其放在bookid列表中:

def rated(request):

    rate = UserRating.objects.filter(userid=request.user.id)[:5]
    bookid =  []

    for i in rates:
        bookid.append(i.bookid)

我想做的就是通过书号获取每本书的海报。显示用户对其海报和价格进行评分的所有书。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

建模非常奇怪:您使用CharField作为将对象链接在一起的一种方式。但这不是一个好习惯。 Django有一个工具可以将模型对象链接在一起:ForeignKey s:

class Book(models.Model):
    poster = models.CharField(max_length=2000)
    title = models.CharField(max_length=150)
    year = models.IntegerField()

    def __str__(self):
        return self.title

class UserRating(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    rating = models.IntegerField()
    book = models.ForeignKey(Books, on_delete=models.CASCADE)

此外,rating可能更是数字,因此,IntegerFieldDecimalField也是如此。模型名称通常为单数(因此,Book而不是Books)。最后,通常不会为模型实例分配id:Django自动执行此操作。如果bookid更像是ISBN,则可以在isbn = ...中创建字段Book

有了这些更改,就可以利用ForeignKey关系,从而使用ORM进行JOIN。例如,我们可以通过以下方式获得用户已评分(连同评分)的所有Book

from django.db.models import F

Book.objects.filter(
    userrating__user=request.user
).annotate(
    rating=F('userrating__rating')
)

在这里,查询集将包含request.user已评分的所有图书。此外, querset的每个Book将具有属性.rating,其中包含该书的用户评分。

我还建议将ManyToManyField模型的Book定义为Userraters),并使其通过UserRating