2015-07-10 4 views
5

Вот мой models.py:TypeError: Int() аргумент должен быть строкой или числом, а не «Model 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 

Я пытаюсь заполнить свою базу данных из файла Excel с помощью xlrd python. Вот мой populate_db.py сценарий:

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

Теперь, когда я бегу сценарий populate_db.py, вывод на терминал гласит: «Проблема Добавление Расположение в меню.». Я вижу, что эта проблема существует здесь в populate_db сценария: m.location.add (л) Но это QuerySet в соответствии с синтаксисом приведенной здесь: https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/

После удаления попробовать/за исключением того, мой отслеживающий читает :

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

Пожалуйста, объясните, что здесь происходит. И как правильно добавить значение к ManyToManyField через запрос.

Возможный дубликат: Django Error: TypeError: int() argument must be a string or a number, not 'BuildsTable' Но я все равно хотел бы знать ответ в моем случае, поскольку я использую ManyToManyField.

Полный отслеживающий:

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

Просьба показать полную информацию о трассе. Если вы удалили try/except здесь, я ожидал бы увидеть ошибку о кортеже, потому что 'get_or_create' возвращает' (экземпляр, созданный) '. –

+0

Да полностью, Обновлено. – vanguard69

+0

** l = (<Место: Indiranagar>, False) ** Это результат от * get_or_create * – vanguard69

ответ

4

Чтобы добавить значение в ManyToManyField, вам нужно добавить объекты, передавая их в качестве аргументов.

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

Это добавит указанные объекты к соответствующему набору объектов.

Вы можете позвонить add(), как показано ниже:

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

В вашем случае, вам нужно сделать:

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

Вы должны получить доступ к instance по индексу 0, как get_or_create возвращает кортеж (instance, created). Затем передайте этот instance методу add().

Примечание:
Использование add() с многими ко многим отношений не будет вызывать какой-либо .save() для каждого объекта, а создавать отношения с использованием .bulk_create().

+0

Это именно то, что я делаю. Не работает. – vanguard69

+0

Вы делаете 'm.location.add (int (value_list [6]))'. Whats 'value_list [6]'? Это объект местоположения –

+1

Этот комментарий является комментарием. Это не то, что я делаю. С другой стороны, я пытаюсь это сделать: 'm.location.add (l)' где 'l = Location.objects.get_or_create (location_name = sq)' – vanguard69

2

Я понимаю, что Рахул Гупта ответил на это уже.Но на более теоретическом уровне я думаю, что это то, что случилось, когда вы используете get_or_create здесь:

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

возвращает кортеж, и, следовательно, вы должны назвать это первый элемент, изменяя его:

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

Которая возвращает только элемент индекса кортежа/словаря!

+1

Yup. Согласен. Это именно то, что происходит. – vanguard69

Смежные вопросы