1

我了解它希望我在访问 M2M 字段之前进行保存。我不想保存模型。我正在使用一个名为 TaskSearchCriteria 的模型来搜索任务。用户可以选择将标准保存到数据库中以供将来搜索。但是应该可以在不保存条件的情况下进行一次性搜索。这是我的模型。

class TaskSearchCriteria(models.Model):
    name = models.CharField(max_length=256)
    task_name = models.CharField(max_length=256, blank=True, null=True)
    project = models.ForeignKey(Project, blank=True, null=True)
    sprint = models.ForeignKey(Sprint, blank=True, null=True)
    type = models.ForeignKey(TaskType, blank=True, null=True)
    priority = models.ForeignKey(Priority, blank=True, null=True)
    status = models.ForeignKey(Status, blank=True, null=True)
    description = models.CharField(max_length=1024, blank=True, null=True)
    owner = models.ForeignKey(User)
    users = models.ManyToManyField(User, related_name='a+')

    def get_param_dict(self):
        retval = dict()
        if self.task_name != None and len(self.task_name) > 0:
            retval["name__contains"] = self.task_name
        if self.project != None:
            retval["project__id"] = self.project.pk
        if self.sprint != None:
            retval["sprint__id"] = self.sprint.pk
        if self.type != None:
            retval["type__id"] = self.type.pk
        if self.priority != None:
            retval["priority__id"] = self.priority.pk
        if self.status != None:
            retval["status__id"] = self.status.pk
        if self.description != None and len(self.description) > 0:
            retval["description__contains"] = self.description
        if self.users != None and len(self.users) > 0: #**ERROR HERE**
            ids = [user.pk for user in self.users]
            retval["users__in"] = ids
        return retval

我使用模型表单来创建模型并运行 get_param_dict() 方法来创建用于 model.object.filter() 的字典。是否可以在不保存到数据库的情况下使用 m2m 字段?

4

1 回答 1

3

简而言之,不,您不能在不保存模型的情况下使用 m2m 字段。

这就是为什么。您必须记住 m2m 字段是如何工作的。与外键不同,m2m 关系需要一个中间表,该表有两个外键指向另外两个表,因此允许任一表(在外键中)有许多行,从而允许多对多行为。因此,为了users在您的模型中检索 ,您必须在数据库中查询users中间 m2m 表,其中外键TaskSearchCriteria是模型实例的主键。只有这样,您才能获得与您的模型关联的用户列表。但是如果你的模型没有保存,那是不可能的,因为你还不能查询中间表。

但是,您可以通过手动向该方法提供用户列表来提供未保存模型实例的解决get_param_dict方法:

def get_param_dict(self, users=[]):
    retval = dict()

    # ...

    # retreive users from the m2m relation
    if self.pk:
        ids = [user_id[0] for user_id in self.users.all().values_list('pk')]
        if ids:
            retval["users__in"] = ids

    # when model is not saved - get user ids from the parameter
    else:
        if users:
            retval["users__in"] = users

    return retval
于 2013-04-10T00:01:33.843 回答