在模板中过滤M2M?

时间:2015-07-13 18:04:53

标签: django django-forms django-views

在我的模型中,我有以下M2M字段

class FamilyMember(AbstractUser):
    ...
    email_list = models.ManyToManyField('EmailList', verbose_name="Email Lists", blank=True, null=True)
    ...

EmailList表如下所示:

class EmailList(models.Model):
    name = models.CharField(max_length=50, default='My List')
    description = models.TextField(blank=True)
    is_active = models.BooleanField(verbose_name="Active")
    is_managed_by_user = models.BooleanField(verbose_name="User Managed")

在应用程序中,用户应该只能看到is_active = True和is_managed_by_user = True的记录。

在管理员方面,管理员应该能够将用户添加到任何/所有这些组,无论is_active和is_managed_by_user标志如何。

管理员会将用户分配给所有电子邮件列表记录。然后,用户登录并且只能看到列表的子集(is_active = True和is_managed_by_user = True)。这是预期的行为。然而,接下来的不是。

用户取消选择电子邮件列表项,然后保存记录。由于M2M_Save在调用save()之前首先清除所有m2m记录,因此我丢失了Admin分配给该用户的所有记录。

我该如何保留?我尝试创建多个列表,然后在保存之前将它们合并,我尝试将整个列表传递给模板,然后隐藏那些is_managed_by_user = False的列表,我只是无法获得任何内容上班。

这对我来说更加棘手的是,这一切都包含在一个formset中。

你会怎么做这个编码?做正确的方法是什么?我是否会过滤掉用户在我的视图中看不到的记录?如果是这样,在保存用户所做的任何更改之前,如何合并这些丢失的记录?

1 个答案:

答案 0 :(得分:0)

您可能想尝试在models.py中设置模型管理器来处理过滤。然后,您可以像views.py那样调用过滤器:

<强> models.py:

class EmailListQuerySet(models.query.QuerySet):
    def active(self):
        return self.filter(is_active=True)
    def managed_by_user(self):
        return self.filter(is_managed_by_user=True)

class EmailListManager(models.Manager):
    def get_queryset(self):
        return EmailListQuerySet(self.model, using=self._db)
    def get_active(self):
        return self.get_queryset().active()
    def get_all(self):
        return self.get_queryset().active().managed_by_user()

class EmailList(models.Model):
    name = models.CharField(max_length=50, default='My List')
    description = models.TextField(blank=True)
    is_active = models.BooleanField(verbose_name="Active")
    is_managed_by_user = models.BooleanField(verbose_name="User Managed")

    objects = EmailListManager()

<强> views.py:

def view(request):
    email = EmailList.objects.get_all()
    return render(request, 'template.html', {'email': email})

显然,我的示例中包含了未完成的数据,欢迎您根据需要更改变量/过滤器。但是,我希望上面的内容可以让您了解可以尝试的可能性。

在您的视图中,您可以执行email = EmailList.objects.all().is_active().is_managed_by_user(),但如果数据库中有很多对象,则加载时间会更长。模型管理器首选节省内存。此外,它不依赖于用户的操作,因此管理员和用户界面都必须直接与模型通信(使它们保持同步)。

注意:上面的示例直接输入到此答案中,尚未在文本编辑器中验证。如果有一些语法错误或拼写错误,我会道歉。