15

私はdjangoを初めて使用し、学習アプリとして経費記録アプリケーションを構築しています。

私のモデルには、次のような 3 つのクラスがあります (簡潔にするために少し簡略化しています)。

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

この問題を回避するためにループを作成できることはわかっていますが、同じことを一度に実行できる、よりエレガントな方法があるのではないかと思います....

4

2 に答える 2

17

モデル インスタンスを作成するときに、そのように m2m フィールドを直接設定することはできません。代わりに次のことを試してください。

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/で、多対多の関係を扱う方法の例を確認できます。

于 2012-04-09T21:28:02.003 に答える
15

私が思いつくことができる最も簡単な方法:

e = Expense(description=self.description,
            amount=self.amount,
            category=self.category,
            date=expense_date)
e.save()
e.tags = self.tags.all()
于 2012-04-10T17:30:56.980 に答える