TypeError: int() argument must be a string or a number, not 'Model Instance'
TypeError: int() argument must be a string or a number, not 'Model Instance'
这是我的 models.py:
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
我正在尝试使用 xlrd
python 模块从 excel 文件填充我的数据库。
这是我的 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(l)
但是这个查询集符合这里给出的语法:https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/
删除 try/except 后,我的回溯显示:
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'.
要向 ManyToManyField 添加值,您需要通过将对象作为参数传递来添加它们。
add(obj1, obj2, obj3, ...)
这会将指定的对象添加到相关对象集中。
您可以像下面这样调用 add()
:
menu_object.location.add(loc_obj1, loc_obj2, ...)
在你的情况下,你需要做:
l = Location.objects.get_or_create(location_name=sq)[0]
您需要通过索引 0
作为 get_or_create
returns 元组 (instance, created)
访问 instance
。然后将此 instance
传递给 add()
方法。
注:
在多对多关系中使用 add()
不会为每个对象调用任何 .save()
,而是使用 .bulk_create()
.
创建关系
我知道 Rahul Gupta 已经回答了这个问题。但在更理论的层面上,我认为当你在这里使用 get_or_create
时会发生这种情况:
l = Location.objects.get_or_create(location_name=sq)
它 returns 是一个元组,因此您必须通过将其修改为以下方式来调用它的第一个元素:
l = Location.objects.get_or_create(location_name=sq)[0]
其中returns只有索引元素tuple/dictionary!
这是我的 models.py:
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
我正在尝试使用 xlrd
python 模块从 excel 文件填充我的数据库。
这是我的 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(l) 但是这个查询集符合这里给出的语法:https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/
删除 try/except 后,我的回溯显示:
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'.
要向 ManyToManyField 添加值,您需要通过将对象作为参数传递来添加它们。
add(obj1, obj2, obj3, ...)
这会将指定的对象添加到相关对象集中。
您可以像下面这样调用 add()
:
menu_object.location.add(loc_obj1, loc_obj2, ...)
在你的情况下,你需要做:
l = Location.objects.get_or_create(location_name=sq)[0]
您需要通过索引 0
作为 get_or_create
returns 元组 (instance, created)
访问 instance
。然后将此 instance
传递给 add()
方法。
注:
在多对多关系中使用 add()
不会为每个对象调用任何 .save()
,而是使用 .bulk_create()
.
我知道 Rahul Gupta 已经回答了这个问题。但在更理论的层面上,我认为当你在这里使用 get_or_create
时会发生这种情况:
l = Location.objects.get_or_create(location_name=sq)
它 returns 是一个元组,因此您必须通过将其修改为以下方式来调用它的第一个元素:
l = Location.objects.get_or_create(location_name=sq)[0]
其中returns只有索引元素tuple/dictionary!