15

我有一个可行的方法,但它似乎很笨拙,我认为有更好的方法来做到这一点。

我有一个模型,将我网站上的用户(用于学习目的的 twitter 克隆)与其他用户列表相关联。

现在,当我创建一个新用户时,我想将该列表初始化为该用户作为列表的成员。

我的模型是:

class FollowerList(models.Model)
    follower = models.ForeignKey(User,related_name="follower")
    followed = models.ManyToManyField(User,related_name="followed")

在我看来,我现在正在使用的代码是

user = User.objects.get(username=uname)
flst = FollowerList()
flst.follower = user
flst.save()
flst.followed.add(user)
flst.save()

在我看来,应该有一种无需调用save()两次即可创建它的方法,但我似乎无法在文档或其他任何地方找到它。

4

3 回答 3

15

你不需要在 many2many.add() 之后调用 save

您还可以将代码缩短为 2 行:

flst = FollowerList.objects.create(follower=user)
flst.followed.add(user)
于 2010-12-23T05:14:27.173 回答
4

虞姬的回答是对的。在保存之前,您不能将对象添加到 M2M 字段。不过,我想提一个更短的创建实例的方法。

user = User.objects.get(username=uname)
flst = FollowerList(follower=user) #use key word args to assign fields
flst.save()
flst.followed.add(user)
# don't need to save after adding an object to many to many field.

我发现这种语法比创建一个空实例和分配字段要好一些。虽然 objects.create() 方法(由 Yuki 提到)更好。

于 2010-12-23T12:10:41.197 回答
2

对此的较晚答案:您还可以覆盖构造函数(__init__),如下所示:

class FollowerList(models.Model):
    follower = models.ForeignKey(User,related_name="follower")
    followed = models.ManyToManyField(User,related_name="followed"

    def __init__(*args, followed=[], **kwargs):
        super(FollowerList, self).__init__(*args, **kwargs)
        self.save()
        for user in followed:
            self.followed.add(user)

即在这里我明确地处理了followed函数中的关键字参数,同时__init__将所有其他参数传递给默认构造函数。调用确保对象已注册,因此可以在 m2m 关系中使用。argskwargssave

然后,这允许您FollowerList使用一行进行创建,例如

flst = FollowerList(follower=user, followed=[user,])

或者,正如 Johannes 所指出的,__init__不希望在 中保存模型。首选的方法是创建一个Manager方法 - 请参阅此处了解详细信息:https ://docs.djangoproject.com/en/1.9/topics/db/managers/ 然后创建一个FollowerList

fl = FollowerList.objects.create(*args, followed, **kwargs)
于 2015-02-07T13:56:20.290 回答