2012-04-09 60 views
7

我是django的新手,作爲一個學習應用程序,我正在構建一個費用日誌記錄應用程序。將ManyToMany字段從一個模型實例複製到另一個

在我的模型有看起來像這樣的三類(我簡化他們稍微爲了簡潔):

class AbstractExpense(models.Model): 
    description = models.CharField(max_length=100) 
    amount  = models.IntegerField() 
    category = models.ForeignKey('Category') 
    tags  = models.ManyToManyField('Tag') 
    insert_date = models.DateTimeField(auto_now=True) 

    class Meta(object): 
     abstract = True 

class Expense(AbstractExpense): 
    date  = models.DateField('Date') 

class RecurringExpense(AbstractExpense): 
    FREQUENCY_CHOICES = (('D', 'daily'), 
         ('W', 'weekly'), 
         ('M', 'monthly'), 
         ('Y', 'yearly')) 
    start_date = models.DateField(blank=False) 
    end_date = models.DateField(blank=True, null=True) 
    last_check = models.DateField(blank=True, null=True) 
    frequency = models.CharField(blank=False, max_length=1, choices=FREQUENCY_CHOICES) 

RecurringExpense只是一個模板:當系統意識到的時候插入一次性費用(例如:租金),它應該將模板中的信息複製到Expense類的新實例中。下面是負責這項工作的RecurringExpense方法的相關位:

Expense(description=self.description, 
     amount=self.amount, 
     category=self.category, 
     # tags=self.tags, 
     date=expense_date).save() 

上述作品完美,但如果我取消了tags=self.tags線,Django的抱怨,並拋出以下錯誤:

Exception Type: TypeError 
Exception Value: 'tags' is an invalid keyword argument for this function 
Exception Location: <snip>/django/db/models/base.py in __init__, line 367 

我知道I could create a loop解決這個問題,但我想知道是否有一個更優雅的方式,可以讓我一次執行相同...

回答

8

我能想出的方法simpliest:

e = Expense(description=self.description, 
      amount=self.amount, 
      category=self.category, 
      date=expense_date) 
e.save() 
e.tags = self.tags.all() 
+1

您也可以用'Expense.objects.create(...)'代替'Expense(...)'/'e.save()' – 2013-12-17 12:59:58

+0

如果您有大量標籤(SQL驅動程序依賴)。在這種情況下,您可以在所有標籤上大塊地迭代以添加它們。 – odedfos 2014-03-17 09:10:21

11

您不能直接設置一個m2m字段,就像創建模型時一樣nstance。而不是嘗試以下操作:

expense = Expense(description=self.description, 
     amount=self.amount, 
     category=self.category, 
     date=expense_date) 
expense.save() 
expense.tags.add(*self.tags.all()) 

您可以檢查https://docs.djangoproject.com/en/1.4/topics/db/examples/many_to_many/關於如何與許多一對多關係的工作更多的例子。

+0

你好,感謝你的回答。爲什麼你使用'.add()'方法並結合列表的拆包,而不是簡單的賦值(請參閱我自己的答案),是否有特定的原因? – mac 2012-04-10 17:33:18

+0

我經常不需要替換現有的m2m關係集,只需添加它即可,所以更習慣於此。對於你的用例,分配比較簡單,應該可以正常工作,因爲'ManyRelatedObjectsDescriptor'在你做後臺任務時在後臺執行'.clear' +'.add(* values)'。 – 2012-04-10 19:00:29

+0

好點。 Upvoted! :) – mac 2012-04-10 20:57:53

相關問題