2010-12-23 148 views
11

我有一個可行的方法,但它看起來很笨拙,我認爲有更好的方法來做到這一點。在Django中使用manytomany字段實例化模型實例

我有一個模型將用戶在我的網站(一個用於學習目的的推特克隆)與其他用戶列表相關聯。

現在,當我創建一個新用戶時,我想用該用戶作爲列表的成員初始化該列表。

我的模式是:

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()兩次,但我似乎無法在文檔或其他任何地方找到它。

回答

12

你並不需要調用many2many.add()

您還可以縮短代碼爲2行後保存:

flst = FollowerList.objects.create(follower=user) 
flst.followed.add(user) 
+0

的問題,當我做到這一點的是,我得到一個錯誤說的FollowerList對象必須有一個主鍵,然後它可以將ManyToManyField實例添加到它。我能看到的唯一方法是先實例化並保存,然後添加其他字段。 – 2010-12-23 06:13:39

+0

那麼,FollowerList.objects.create(follower = user)會給它一個主鍵。它保存。 – 2010-12-23 06:15:09

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提到)仍然更好。

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) 

即在這裏,我明確地處理在__init__功能followed關鍵字參數,而通過所有其他argskwargs默認的構造函數。 致電save確保對象已註冊,因此可用於m2m關係。

這就允許你做一個行創建FollowerList,如

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

另外,由約翰內斯指出,節約的__init__一種模式是無法預期的。首選的方法是創建一個Manager方法 - 在這裏看到的細節:https://docs.djangoproject.com/en/1.9/topics/db/managers/ ,然後創建一個FollowerList

fl = FollowerList.objects.create(*args, followed, **kwargs)