Django:在对象创建期间使用 ManyToMany-field 作为关键字会导致 TypeError

Django: using ManyToMany-field as keyword during object creation causes TypeError

当 运行 调用 Django 模型创建时,我收到如下错误消息:

TypeError: 'keywords' is an invalid keyword argument for this function

创建的对象在 ModelViewset 中称为 form,如下所示:

the_item = Item.objects.create(url=the_photo_url, owner=the_user, keywords=the_keywords, item_type=the_item_type, title=the_title)

我的项目模型如下所示(它有一个链接到关键字 table 的关键字字段):

class Item(models.Model):

    ITEM_TYPES = (
        ('V', 'Vine'),
        ('Y', 'YouTube'),
        ('P', 'Photo'),         # Photo is stored by us on a CDN somewhere
        ('F', 'Flickr'),
        ('I', 'Instagram'),
        ('D', 'DeviantArt'),
        ('5', '500px'),
    )
    owner = models.ForeignKey(User, on_delete=models.CASCADE)     
    title = models.CharField(max_length=60, default='')           
    url = models.CharField(max_length=250, default='', unique=True)
    item_type = models.CharField(max_length=1, choices=ITEM_TYPES)    
    keywords = models.ManyToManyField(Keyword, related_name='keywords')
    credits_applied = models.IntegerField(default=5000)
    credits_left = models.IntegerField(default=10)
    credits_gifted = models.IntegerField(default=0)
    date_added = models.DateTimeField(auto_now_add=True)               
    liked = models.IntegerField(default=0)                        
    disliked = models.IntegerField(default=0)                        
    active = models.BooleanField(default=True)
    comment = models.CharField(max_length=100, blank=True)         
    approved = models.BooleanField(default=0)                      

相关的关键字模型如下所示:

class Keyword(models.Model):
    name = models.CharField(max_length=30)

Item.objects.create()the_keyords 参数是一个 Python 列表:[1,21]

为什么 Django 抱怨关键字参数?

您不能像在创建模型实例时那样使用 ManyToMany 字段。对于创建必要的通过模型实例,必须先保存对象(要有pk)。所以先创建实例,然后使用add方法添加Keyword个实例(一次可以添加多个):

the_item = Item.objects.create(...)  

keywords = list(Keyword.objects.filter(id__in=[1, 21]))
the_item.keywords.add(*keywords)

或者,也许性能更高一点,使用直通模型和 bulk_create 直接将减少整个添加到一个数据库的命中:

kw_ids = [1, 21]
through_model = Item.keywords.through
through_model.bulk_create(
    [through_model(item_id=the_item.pk, keyword_id=kw_id) for kw_id in kw_ids]
)