2016-01-21 50 views
0

models.py填充ManyToManyField

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

這對於成分和餡料,但不是比薩劇本的工作。

error(抱歉格式):

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

任何幫助嗎?我讀的地方,我應該離開澆頭空白,並在以後添加,但...

回答

1

當你創建一個具有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 

我認爲應該工作。

0

的IT工作,謝謝。

這裏我在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