【问题标题】:Django Assign M2M after Saving保存后 Django 分配 M2M
【发布时间】:2013-03-27 12:06:42
【问题描述】:

我正在使用 Django 进行一个项目,但遇到以下问题:

我有这两个类,Team 和 Project。当我创建一个项目时,我想自动将团队中的用户分配给我在创建项目时选择的新项目。 我覆盖了项目的保存方法,并在创建项目后将用户分配给项目(我在保存后做了,因为之前给了我一个错误)。我尝试了几种方法,但没有一种方法有效。 试用者:

self.user.add(*self.team.users.all())
self.save()

这不起作用。

尝试迭代:

for uTeam in self.team.users.all():
    self.users.add(uTeam)

也不起作用。

对我有用的唯一方法是这样,但仅限于 Django Shell:

P = Project.objects.get(pk=1)
T = Team.objects.get(pk=1)
P.user.add(*T.user.all())
P.save()

这是我下面的解决方案,但在 Django 中不起作用(提供无限循环)

class Team(models.Model):
    name = models.CharField(max_length=200,
                            help_text=_('name of the team'))
    user = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                related_name="members_of_team",
                                help_text=_('users of the team'),
                                null=True
                                )
    and more....


class Project(models.Model):
    id = models.AutoField(primary_key=True, null=False)
    name = models.CharField(max_length=200,
                            help_text=_('name of project'),
                            )
    team = models.ForeignKey(Team,`enter code here`
                             on_delete=models.PROTECT,
                             help_text=_('team of project'))
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL,
                                  on_delete=models.PROTECT,
                                  related_name='creator_project',
                                  blank=True,
                                  null=False,
                                  help_text=_('project created by'))
    customer = models.ForeignKey(Customer,
                                on_delete=models.PROTECT,
                                help_text=_('customer'))
    user = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                  related_name='users_team',
                                  blank=True,
                                  null=False,
                                  help_text=_('users of this project'))


   def save(self, *args, **kwargs):

     if self.checkIntegrity():
       super(Project, self).save(*args, **kwargs)
       if self.user.all().count() < self.team.user.all().count():
         T = Team.objects.get(pk=self.team.id)
         P = Project.objects.get(pk=self.id)
         P.user.add(*T.user.all())
         P.save()

感谢您的帮助

【问题讨论】:

  • 只是为了澄清 - 在保存项目本身之前将用户添加到项目会引发异常,因为项目还没有主键,所以你不能将用户分配给(在那一刻)不存在的项目。接下来-afaik 在迭代中添加用户(您的第二次尝试)和将它们添加为列表(您在save() 中的当前代码)之间应该没有任何区别。你有一些调试信息,如果它真的通过那个 for 循环循环?
  • 发生的事情是 P.save() 调用 Project 的 save 并检查完整性,调用 super(Project, Self),再次分配 T 和 P,并再次添加用户......我注意到已分配但进入无限循环,一段时间后会出现“RuntimeError:最大递归深度超出”
  • 是的,这是有道理的。但是调用P.save()(最后一行不是必需的,对吧?
  • 我试过不使用 P.save(),但它没有保存任何东西。奇怪的是,当我在 django shell 中执行此操作时,我不需要保存该实例,但在 django 模型中我必须保存。我也尝试过编写原始 SQL,但也不起作用。我一直在检查制作 django 的 SQL 语句,我发现一些奇怪的东西。首先我看到这个语句: INSERT INTO time_counter_project_user (project_id, user_extended_id) VALUES (109, 1), (109, 2) 这由我创建的 post_signal 函数调用。
  • 但后来我得到这个语句:DELETE FROM time_counter_project_user WHERE time_counter_project_user.project_id = 109 来自:python/lib/python2.7/site-packages/django/contrib/admin/ save_related(762) form.save_m2m() 中的 options.py 所以我认为如果将表单留空,则会尝试删除之前添加的所有内容。有什么解决办法?

标签: django m2m


【解决方案1】:

我明白了,我读到 m2m 字段在 save() 和 post_save() 之后填充,并且当 m2m 字段更改时会触发一个信号,所以我写了以下内容:

@receiver(m2m_changed, sender=Project.user.through)
def m2mChange(sender, **kwargs):
    instance = kwargs['instance']
    T = Team.objects.get(pk=instance.team.id)
    if kwargs['pk_set'] is None:
         instance.user.add(*T.user.all())

现在它工作正常。 谢谢大家。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多