2015-07-10 26 views
5

Oto mój models.py:TypeError: int() Argument musi być ciągiem lub numer, a nie 'Wzór Instance'

from django.db import models 

class Location(models.Model): 
    location_name = models.CharField(max_length=100) 
    def __unicode__(self): 
     return self.location_name 

class Menu(models.Model): 
    location = models.ManyToManyField(Location) 
    restaurant_name = models.CharField(max_length=200) 
    dish_category = models.CharField(max_length=100) 
    dish_name = models.CharField(max_length=200) 
    VNV_tag = models.CharField(max_length=100) 
    quantity = models.CharField(max_length=10, default='FULL') 
    price = models.CharField(max_length=5, default=0) 
    def __unicode__(self): 
     return self.restaurant_name 

staram się zapełnić mojej bazy danych z pliku programu Excel przy użyciu xlrd moduł python. Oto mój populate_db.py scenariusz:

import os 
import xlrd 
from menusearch.models import Menu, Location 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'midnitepro.settings') 
import django 
django.setup() 

def populate(): 
    book = xlrd.open_workbook('/Users/Sahil/Desktop/MNFP1.xlsx') 
    sheet = book.sheet_by_index(0) 
    count1 = 0 
    while count1<sheet.nrows: 
     value_list = [] 
     count2 = 0 
     while count2<sheet.ncols: 
      value_list.append(sheet.row_values(count1, start_colx=count2, end_colx=count2+1)) 
      count2 +=1 
     add_menuitem(value_list) 
     count1 += 1 

def add_menuitem(value_list): 
    split_query = [] 
    m = Menu.objects.create() 
    value_list = [str(x[0]).encode('utf-8') for x in value_list if x] 

    m.restaurant_name = (value_list[0]) 
    m.dish_category = (value_list[1]) 
    m.dish_name = (value_list[2]) 
    m.VNV_tag = (value_list[3]) 
    m.quantity = (value_list[4]) 
    m.price = (value_list[5]) 
    # m.location.add(int(value_list[6])) 

    split_query = (value_list[6]).split(",") 
    for sq in split_query: 
     l = Location.objects.get_or_create(location_name=sq) 
     try: 
      m.location.add(l) 
     except ValueError: 
      print "Problem Adding Location to Menu." 

    m.save() 

if __name__ == '__main__': 
    print "Starting population script..." 
    from menusearch.models import Menu, Location 
    populate() 

Teraz, gdy uruchomić skrypt populate_db.py, wyjście na terminalu brzmi: "Problem Dodanie Lokalizacja Menu.". Widzę, że problem istnieje tutaj w skrypcie populate_db: m.location.add (L) Ale to queryset jest zgodna ze składnią danego tutaj: https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/

Po usunięciu spróbuj/z wyjątkiem, mój traceback czyta :

TypeError: int() argument must be a string or a number, not 'Location' 

Proszę wyjaśnić, co się tutaj dzieje. A jak poprawnie dodać wartość do ManyToManyField za pomocą zestawu zapytań.

Prawdopodobny duplikat: Django Error: TypeError: int() argument must be a string or a number, not 'BuildsTable' Ale nadal chciałbym znać odpowiedź w moim przypadku, ponieważ używam ManyToManyField.

Pełna traceback:

l= (<Location: Indiranagar>, False) 

Inside Loop - sq= Indiranagar 
Traceback (most recent call last): 
    File "populate_db.py", line 62, in <module> 
populate() 
    File "populate_db.py", line 23, in populate 
add_menuitem(value_list) 
    File "populate_db.py", line 50, in add_menuitem 
m.location.add(l) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/fields/related.py", line 973, in add 
self._add_items(self.source_field_name, self.target_field_name, *objs) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/fields/related.py", line 1079, in _add_items 
'%s__in' % target_field_name: new_ids, 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 679, in filter 
return self._filter_or_exclude(False, *args, **kwargs) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 697, in _filter_or_exclude 
clone.query.add_q(Q(*args, **kwargs)) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1304, in add_q 
clause, require_inner = self._add_q(where_part, self.used_aliases) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1332, in _add_q 
allow_joins=allow_joins, split_subq=split_subq, 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1194, in build_filter 
lookups, value) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/fields/related.py", line 1745, in get_lookup_constraint 
root_constraint.add(lookup_class(targets[0].get_col(alias, sources[0]), value), AND) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/lookups.py", line 96, in __init__ 
self.rhs = self.get_prep_lookup() 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/lookups.py", line 134, in get_prep_lookup 
return self.lhs.output_field.get_prep_lookup(self.lookup_name, self.rhs) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 729, in get_prep_lookup 
return [self.get_prep_value(v) for v in value] 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 985, in get_prep_value 
return int(value) 
TypeError: int() argument must be a string or a number, not 'Location'. 
+1

Proszę podać pełne informacje zwrotne. Jeśli usunąłeś try/except tutaj, spodziewałbym się zobaczyć błąd dotyczący krotki, ponieważ 'get_or_create' zwraca' (instance, created) '. –

+0

Tak, całkowicie zaktualizowany. – vanguard69

+0

** l = (, False) ** To jest wynik z * get_or_create * – vanguard69

Odpowiedz

4

Aby dodać wartość do ManyToManyField, trzeba dodać obiekty przekazując je jako argumenty.

add(obj1, obj2, obj3, ...) 

Spowoduje to dodanie określonych obiektów do powiązanego zestawu obiektów.

można nazwać add() jak poniżej:

menu_object.location.add(loc_obj1, loc_obj2, ...) 

W twoim przypadku, trzeba zrobić:

l = Location.objects.get_or_create(location_name=sq)[0] 

Trzeba otworzyć instance indeksem 0 jak get_or_create zwraca tuple (instance, created). Następnie przeprowadź tę metodę instance do metody add().

Uwaga:
Korzystanie add() z wielu do wielu relacji nie będzie wywoływać żadnych .save() dla każdego obiektu, ale raczej tworzyć relacje z wykorzystaniem .bulk_create().

+0

To jest dokładnie to, co robię. Nie działa. – vanguard69

+0

Robisz 'm.location.add (int (value_list [6]))'. Co 'value_list [6]'? Czy to obiekt lokalizacji –

+1

To stwierdzenie jest komentarzem. Nie to robię. Z drugiej strony próbuję tego: 'm.location.add (l)' gdzie 'l = Location.objects.get_or_create (location_name = sq)' – vanguard69

2

Rozumiem, że Rahul Gupta już na nie odpowiedział.Jednak na poziomie bardziej teoretycznym myślę, że to, co stało się podczas korzystania get_or_create tutaj:

l = Location.objects.get_or_create(location_name=sq) 

Zwraca krotki, a więc trzeba zadzwonić to pierwszy element, modyfikując go:

l = Location.objects.get_or_create(location_name=sq)[0] 

Który zwraca tylko element indeksu krotki/słownika!

+1

Yup. Zgadzam się. Dokładnie to się dzieje. – vanguard69