【问题标题】:Django models for social media apps ValueError in ManyToManyFieldManyToManyField 中社交媒体应用 ValueError 的 Django 模型
【发布时间】:2020-01-30 11:49:48
【问题描述】:

我正在构建一个社交媒体应用程序。

这是我的模型:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=50)

class Group(models.Model):
    admin = models.ManyToManyField(Person, related_name='admin')
    members = models.ManyToManyField(Person, blank=True, related_name='members')

    def save(self, *args, **kwargs):
        self.members.add(self.admin)
        super(Group, self).save(*args, **kwargs)

当我尝试创建新组时,由于覆盖 save 方法而引发以下错误..

/admin/social/group/add/处的ValueError

"<Group: Group object (None)>" needs to have a value for field "id" before this many-to-many relationship can be used.

我想要一个组的admin 也将是同一组的members,这就是为什么我覆盖了 save 方法但它抛出了上面的错误。

我也尝试使用 Django signal 来实现这一点,如下所示

@receiver(post_save, sender=Group)
def make_admin_also_members(sender, instance, created, **kwargs):
    if created:
        instance.members.add(instance.admin)
        instance.save()

它会引发以下错误:

TypeError at /admin/social/group/add/

int() argument must be a string, a bytes-like object or a number, not 'ManyRelatedManager'

然后我尝试像这样实现它:

@receiver(post_save, sender=Group)
def make_admin_also_members(sender, instance, created, **kwargs):
    if created:
        instance.members.add(str(instance.admin))
        instance.save()

它引发了以下错误:

    ValueError at /admin/social/group/add/

invalid literal for int() with base 10: 'social.Person.None'

遇到上述错误后,我尝试如下实现此目标

@receiver(post_save, sender=Group)
def make_admin_also_members(sender, instance, created, **kwargs):
    if created:
        instance.members.add((member.id for member in instance.admin))
        instance.save()

我被这个错误弄伤了:

TypeError at /admin/social/group/add/

'ManyRelatedManager' object is not iterable

如果我像下面这样尝试:

@receiver(post_save, sender=Group)
def make_admin_also_members(sender, instance, created, **kwargs):
    if created:
        instance.members.add(*instance.admin.all())
        instance.save()

它不会引发任何错误,但问题是,它没有保存 members 字段。

谁能帮我实现这个目标?

【问题讨论】:

  • 您确定admin 应该是ManyToManyField 吗?一个组可以有多个管理员吗? (如果是这样,至少你应该叫它admins。)

标签: django django-models django-rest-framework


【解决方案1】:

它抱怨你不能迭代 instance.admin 本身,只能迭代 instance.admin<b>.all()</b>

您可以在此处使用可迭代解包,以便更方便地添加人员。请注意,如果您更改多对多关系,您不必必须instance.save(),因为它保存在两个模型之间的“隐藏”模型中。

@receiver(post_save, sender=Group)
def make_admin_also_members(sender, instance, created, **kwargs):
    if created:
        instance.members.add(*instance.admin.all())

话虽如此,如果您使用ModelForm,它仍然无法正常工作。确实,既然一个模型表单会先保存组,然后再添加成员。所以post_save 将在您添加管理员成员之前被触发。

所以我猜如果你没有在save(..) 函数中添加值,而是使用ModelForm,你应该在视图 中执行逻辑。因此,您可以将其定义为:

def some_view(request):
    # ...
    if request.method == 'POST':
        form = MyModelFrom(request.POST)
        if form.is_valid():
            instance = form.save()
            instance.members.add(*instance.admin.all())
    # …

【讨论】:

  • @mamuncode: 那么看起来你的admin 并没有在你保存Group 后立即保存,如果你使用模型表单这是合乎逻辑的:)
  • 怎么样?在这种情况下可以帮助我吗?
  • 稍后我会序列化Group,所以我认为modelform不会解决我的问题
  • @mamuncode:模型表单不会解决问题,我只是说创建具有m2m关系的对象的控制流程是首先保存对象(并且因此也触发post_save),然后然后添加m2m项目。所以post_save触发器被触发之前instance.admin中有任何成员。
  • 你能帮我写代码吗?我从来没有尝试过这种任务......
猜你喜欢
  • 1970-01-01
  • 2020-01-22
  • 2014-02-24
  • 2018-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-12
  • 2020-03-03
相关资源
最近更新 更多