与额外字段的多对多关系是否适合我的工作?

时间:2009-08-18 05:04:37

标签: django django-models

Previously已经开始询问这个问题的更具体版本,但很难明确我的问题。反思使我怀疑我所选择的解决方案是否对问题是正确的,所以这次我将解释问题并询问a)我是否在正确的轨道上b)如果我现在的砖墙周围有一条路。 / p>

我目前正在构建一个Web界面,以便(少数)用户可以查询现有数据库。坚持使用文档中的类比,我的模型看起来像这样:

class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    dob = models.DateField()

class Album(models.Model):
    artist = models.ForeignKey(Musician)
    name = models.CharField(max_length=100)

class Instrument(models.Model):
    artist = models.ForeignKey(Musician)
    name = models.CharField(max_length=100)

我有一个中心表(音乐家)和几个由ForeignKey或OneToOneFields相关的关联数据表。用户通过创建过滤条件与数据库交互,以根据主要或相关表上的数据选择音乐家的子集。同样,用户然后可以选择使用哪个数据来对呈现给他们的结果进行排名。然后,结果最初被视为一个二维表,每个音乐家有一行,每列中都有选定的数据字段(或聚合)。

为了让您了解规模,该数据库拥有约5,000名音乐家,其中包含约20个相关数据字段。

到目前为止这很好,我有一个有效的实施。但是,重要的是我能够让给定用户上传自己的注释数据集(多个),然后按照与现有数据相同的方式对这些数据集进行过滤和排序。

我尝试这样做的方法是添加模型:

class UserDataSets(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=64)
    results = models.ManyToManyField(Musician, through='UserData')

class UserData(models.Model):
    artist = models.ForeignKey(Musician)
    dataset = models.ForeignKey(UserDataSets)
    score = models.IntegerField()

    class Meta:
        unique_together = (("artist", "dataset"),)

我有一个简单的上传机制,使用户能够上传一个数据集文件,该文件由音乐家和他们的“分数”之间的1对1关系组成。在给定的用户数据集中,每个艺术家都是唯一的,但不同的数据集彼此独立,并且通常包含同一个音乐家的条目。

这对于显示数据很好,从给定的艺术家开始,我可以这样做:

artist = Musician.objects.get(pk=1)
dataset = UserDataSets.objects.get(pk=5)
print artist.userdata_set.get(dataset=dataset.pk)

然而,当我根据单个用户数据集中包含的数据实现音乐家查询集的过滤和排序时,这种方法就失败了。例如,我可以根据UserData表中的所有数据轻松地对查询集进行排序,如下所示:

artists = Musician.objects.all().order_by(userdata__score)

但这并没有帮助我按给定的单个用户数据集的结果进行排序。同样地,我需要能够基于来自不同用户数据集的“得分”来过滤查询集(例如,找到数据集1中得分> 5且数据集2中<2的所有音乐家)。

有没有办法做到这一点,还是我整个错误的方法?

1 个答案:

答案 0 :(得分:0)

编辑:没关系,这是错的。我会保留它以便你可以阅读,但之后我会删除。

您好,

如果我理解正确,你可以尝试这样的事情:

artists = Musician.objects.select_related('UserDataSets').filter( Q(userdata__score_gt=5, userdata__id=1) | Q(userdata__sorce_lt=2, userdata__id=2 ) 

有关如何使用Q的详细信息,请查看:Complex lookups with Q objects