TypeError:int()参数必须是字符串或数字,而不是“模型实例” [英] TypeError: int() argument must be a string or a number, not 'Model Instance'

查看:151
本文介绍了TypeError:int()参数必须是字符串或数字,而不是“模型实例”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的 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 脚本:

I am trying to populate my database from an excel file using xlrd python module. Here's my populate_db.py script:

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/

Now when I run the populate_db.py script, the output on the terminal reads: "Problem Adding Location to Menu.". I see that the problem exists here in the populate_db script: m.location.add(l) But this queryset is in line with the syntax given here: https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/

删除try / except之后,我的追溯如下:

After removing the try/except, my traceback reads:

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

请说明这里发生了什么。
如何正确地通过查询器向 ManyToManyField 添加一个值。

Please explain what is happening here. And how to properly add a a value to the ManyToManyField via a queryset.

可能的重复: Django错误:TypeError:int()参数必须是字符串或数字,而不是BuildsTable
但是我会在我使用ManyToManyField的时候,仍然想知道答案。

Possible duplicate: Django Error: TypeError: int() argument must be a string or a number, not 'BuildsTable' But I would still like to know the answer in my case as I'm using a 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添加值,您需要通过传递它们作为参数来添加对象。

To add a value to a ManyToManyField, you need to add the objects by passing them as arguments.

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

这将把指定的对象添加到相关的对象集。

This will add the specified objects to the related object set.

您可以调用 add(),如下所示:

You can call the add() like below:

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

在你的情况下,你需要要做:

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

您需要通过索引访问实例 c> 0 as get_or_create 返回一个元组(实例,创建)。然后将这个实例传递给 add()方法。

You need to access the instance by index 0 as get_or_create returns a tuple (instance, created). Then pass this instance to the add() method.

注意:

使用 add()多对多关系不会为每个对象调用任何 .save(),而是使用 .bulk_create()

Note:
Using add() with a many-to-many relationship will not call any .save() for each object, but rather create the relationships using .bulk_create().

这篇关于TypeError:int()参数必须是字符串或数字,而不是“模型实例”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆