python - 填充多对多字段

标签 python django m2m

我的models.py

class Ingredient(models.Model):
    name = models.CharField(max_length=16, unique=True)
    price = models.SmallIntegerField()
    def __str__(self):
        return self.name

class Topping(models.Model):
    name = models.CharField(max_length=32)
    ingredient = models.ForeignKey(Ingredient, related_name='indole', 
        blank=True, null=True, default='base')
    def __str__(self):
        return self.nome

class Pizza(models.Model):
    nome = models.CharField(max_length=32, unique=True)
    toppings = models.ManyToManyField(Topping)
    def __str__(self):
        return self.nome

在管理员中它可以工作!我可以添加配料、披萨等。但我想使用脚本来填充。

我的脚本:

import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'recipt.settings')

import django
django.setup()

from core.models import *

def populate():
    cheap = add_ingredient('Cheap', 3)
    base = add_ingredient('Base', 5)
    good = add_ingredient('Good', 10)

    cheese = add_topping('Cheese', None)
    tomato = add_topping('Tomato', None)
    olive = add_topping('Olive', None)  

    simple = add_pizza('Simple', cheese) #just one toppings for now
    complex = add_pizza('Complex', tomato)

def add_ingredient(name, price):
    i = Ingredient.objects.get_or_create(name=name, price=price)[0]
    i.save()
    return i

def add_topping(name, ingredient):
    t = Topping.objects.get_or_create(name=name, ingredient=ingredient)[0]
    t.save()
    return t

def add_pizza(name, toppings):
    p = Pizza.objects.get_or_create(name=name, toppings=toppings)[0]
    p.save()
    return p

if __name__ == '__main__':
    print ("Starting Core population script...")
    populate()

此脚本适用于配料和配料,但不适用于披萨。

我的错误(抱歉格式错误):

Starting Core population script...

Traceback (most recent call last):

File "c:\Python34\Scripts\recipt\myvenv\lib\site-packages\django\db\mode ls\query.py", line 465, in get_or_create

return self.get(**lookup), False
File "c:\Python34\Scripts\recipt\myvenv\lib\site-packages\django\db\mode ls\query.py", line 387, in get

self.model._meta.object_name

core.models.DoesNotExist: Pizza matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "populate_core.py", line 437, in module

populate()
File "populate_core.py", line 63, in populate

simple = add_pizza('Simple', cheese)
File "populate_core.py", line 307, in add_pizza

p = Pizza.objects.get_or_create(name=name, toppings=toppings)[0]
File "c:\Python34\Scripts\recipt\myvenv\lib\site-packages\django\db\mode ls\manager.py", line 122, in manager_method

return getattr(self.get_queryset(), name)(*args, **kwargs)
File "c:\Python34\Scripts\recipt\myvenv\lib\site-packages\django\db\mode ls\query.py", line 467, in get_or_create

return self._create_object_from_params(lookup, params)
File "c:\Python34\Scripts\recipt\myvenv\lib\site-packages\django\db\mode ls\query.py", line 499, in _create_object_from_params

obj = self.create(**params)
File "c:\Python34\Scripts\recipt\myvenv\lib\site-packages\django\db\mode ls\query.py", line 399, in create

obj = self.model(**kwargs)
File "c:\Python34\Scripts\recipt\myvenv\lib\site-packages\django\db\mode ls\base.py", line 443, in init

raise TypeError("'%s' is an invalid keyword argument for this function" % li st(kwargs)[0]) TypeError: 'toppings' is an invalid keyword argument for this function

请问有什么帮助吗?我在某处读到我应该将配料留空并稍后添加,但是......

最佳答案

当您创建具有ManyToMany字段的数据库记录时,您无法正常执行此操作。您必须创建对象,然后将内容添加到ManyToMany 字段。像这样的东西。

class Author(models.Model):
    name = models.CharField(max_length=100)
class Article(models.Model):
    name = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
zach = Author("Zach Braff")
zach.save()
# Say Zach writes an article...
# You can't do this because the authors field could have many things in it. 
a1 = Article(name="Scrubs remake coming?", authors=zach)

# Instead, you have to do this...
a1 = Article(name="Scrubs remake coming?")
a1.authors.add(zach)

a1.save()

您可能想要做的是将 get_or_create() 替换为有效的等效项,如下所示。

p = Pizza.objects.filter(name=name, toppings=toppings)
# This is faster than `if p`
if p.exists():
   return p
else:
    p = Pizza.objects.create(name=name)
    p.toppings.add(toppings)
    p.save()
    return p

我认为这应该可行。

关于python - 填充多对多字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34913632/

相关文章:

Django 1.8 - 中间多对多直通关系 - 使用 'ManytoManyField' 的结果是什么?

python - 如何检查 NumPy 和 SciPy 中的 BLAS/LAPACK 链接?

python - 无法在 Mac OS X 10.9.5 上安装 uWSGI

python - 我可以做一个 django 获取最新版本 ==

python - 我是否在 Django 测试中 mock 这个辅助函数?

python - DRF - 使用直通模型进行 m2m 字段的嵌套序列化

python - 记录特定消息

Python ctypes 设置 c_char_p 底层值

django - 何时应使用 Django 自引用外键?为什么?

django - 列表字段序列化程序给出 'ManyRelatedManager' 对象不是 M2M 字段的可迭代错误