我了解它要我在访问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字段而不保存到数据库?

最佳答案

简而言之,不,您必须在不保存模型的情况下使用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

10-06 06:18