Copying ManyToMany fields from one model instance to another

I am new to django, and as a training application I am creating an application for recording expenses.

In my models, I have three classes that look like this (I simplified them a bit for brevity):

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 is just a template: when the system understands that it is time to insert recurring expenses (for example, rent), it should take the information in the template and copy it to a new instance of the Expense class. Here is the corresponding bit from the RecurringExpense method responsible for working:

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

This works flawlessly, but if I uncomment the tags=self.tags , django complains and throws the following error:

 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 know. I could create a loop to get around this problem, but I wonder if there is a more elegant way that would allow me to do the same right away ....

+7
source share
2 answers

The easiest way:

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

You cannot set the m2m field directly as you did when creating the model instance. Instead, try the following:

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

You can check https://docs.djangoproject.com/en/1.4/topics/db/examples/many_to_many/ for more examples of how to work with many-to-many relationships.

+11
source

All Articles