填充ManyToManyField

时间:2016-01-21 01:06:25

标签: 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

在管理员工作!我可以添加打顶,披萨等。但我想使用脚本来填充。

我的script

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()

此脚本适用于配料和浇头,但不适用于Pizza。

我的error(对不起格式化):

  

启动核心人口脚本...

     

追踪(最近一次呼叫最后一次):

     

文件“c:\ Python34 \ Scripts \ _________tov \ lib \ site-packages \ django \ db \ mode \ nls \ query.py”,第465行,get_or_create

     

返回self.get(**查找),False
  文件“c:\ Python34 \ Scripts \ _________tov \ lib \ site \ packages \ django \ db \ mode   ls \ query.py“,第387行,在get

中      

self.model._meta.object_name

     

core.models.DoesNotExist:匹配匹配查询不存在。

     

在处理上述异常期间,发生了另一个异常:

     

追踪(最近的呼叫最后):
  在模块

中输入“populate_core.py”,第437行      

填入()
  在填充中的文件“populate_core.py”,第63行      

simple = add_pizza('简单',奶酪)
  在add_pizza

中输入“populate_core.py”,第307行      

p = Pizza.objects.get_or_create(name = name,toppings = toppings)[0]
  在manager_method中的文件“c:\ Python34 \ Scripts \ _supportt \ myvenv \ lib \ site-packages \ django \ db \ mode ls \ manager.py”,第122行

     

return getattr(self.get_queryset(),name)(* args,** kwargs)
  在get_or_create中输入文件“c:\ Python34 \ Scripts \ _supportt \ myvenv \ lib \ site-packages \ django \ db \ mode ls \ query.py”,第467行

     

return self._create_object_from_params(lookup,params)
  在_create_object_from_params

中输入文件“c:\ Python34 \ Scripts \ _________tov \ lib \ site-packages \ django \ db \ mode ls \ query.py”,第499行      

obj = self.create(** params)
  在创建文件“c:\ Python34 \ Scripts \ _supportt \ myvenv \ lib \ site-packages \ django \ db \ mode \ nls \ query.py”,第399行,创建

     

obj = self.model(** kwargs)
  在 init

中输入文件“c:\ Python34 \ Scripts \ _supportt \ myvenv \ lib \ site-packages \ django \ db \ mode \ nls \ base.py”,第443行      

引发TypeError(“'%s'是此函数的无效关键字参数”%li st(kwargs)[0])TypeError:'toppings'无效   此函数的关键字参数

请帮忙吗?我读到某个地方我应该把配料留空并稍后再加......但是......

2 个答案:

答案 0 :(得分:2)

当您创建具有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

我认为应该有效。

答案 1 :(得分:0)

工作,谢谢。

这是script中的新代码:

simple = add_pizza('Simple', [cheese, tomato])
complex = add_pizza('Complex', [cheese, tomato, olive])

def add_pizza(name, toppings):
    p = Pizza.objects.filter(name=name)
    if p.exists():
        pass
    else:
    p = Pizza.objects.create(name=name)
    for t in toppings:
        p.toppings.add(t)
    p.save()
    return p