2015-07-10 16 views
5

Hier ist mein models.py:Typeerror: int() Argument muss eine Zeichenkette oder eine Zahl sein, nicht ‚Modell Instanz‘

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 

Ich versuche, meine Datenbank aus einer Excel-Datei zu füllen xlrd mit Python-Modul. Hier ist mein populate_db.py Skript:

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

Nun, wenn ich das populate_db.py Skript ausführen, die Ausgabe auf dem Terminal liest: "Problem Lage Menü Hinzufügen.". Ich sehe, dass das Problem hier im populate_db Skript vorhanden: m.location.add (l) Aber diese queryset steht im Einklang mit der Syntax hier gegeben: https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/

Nach dem Entfernen des try/except, meine Zurückverfolgungs lesen :

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

Bitte erklären Sie, was hier passiert. Und wie fügt man einen Wert ManyToManyField über ein Abfrage-Set ordnungsgemäß hinzu.

Mögliche Duplikate: Django Error: TypeError: int() argument must be a string or a number, not 'BuildsTable' Aber ich würde immer noch gerne die Antwort in meinem Fall wissen, wie ich ein ManyToManyField verwende.

Vollzurückverfolgungs:

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

Bitte zeigen Sie die vollständige Traceback. Wenn Sie die try/exception hier entfernen, würde ich erwarten, dass ein Fehler in einem Tupel auftritt, weil 'get_or_create'' (instance, created) 'zurückgibt. –

+0

Ja total, aktualisiert. – vanguard69

+0

** l = (, False) ** Dies ist die Ausgabe von * get_or_create * – vanguard69

Antwort

4

Um einen Wert zu einem ManyToManyField hinzufügen können, müssen Sie die Objekte hinzufügen, indem Sie sie als Argumente zu übergeben.

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

Dadurch werden die angegebenen Objekte zum zugehörigen Objektsatz hinzugefügt.

können Sie rufen die add() wie unten:

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

In Ihrem Fall, was Sie tun müssen:

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

Sie müssen die instance von Index 0 als get_or_create liefert ein für den Zugriff auf Tupel (instance, created). Dann übergeben Sie diese instance an die add() Methode.

Hinweis:
Mit add() mit einem many-to-many-Beziehung wird jede .save() für jedes Objekt nicht nennen, sondern die Beziehungen schaffen .bulk_create() verwenden.

+0

Dies ist genau das, was ich tue. Funktioniert nicht. – vanguard69

+0

Sie tun 'm.location.add (int (value_list [6]))'. Was ist 'value_list [6]'? Ist es das Standortobjekt –

+1

Diese Aussage ist ein Kommentar. Das tue ich nicht. Auf der anderen Seite versuche ich dies: 'm.location.add (l)' wo 'l = Location.objects.get_or_create (location_name = sq)' – vanguard69

2

Ich verstehe, dass Rahul Gupta dies bereits beantwortet hat.Aber auf einer theoretischen Ebene ich denke, das ist, was passiert, wenn Sie get_or_create hier verwenden:

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

Es ein Tuple zurückkehrt, und daher müssen Sie nennen es das erste Element ist durch Modifizieren Sie es an:

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

Das gibt nur das Indexelement des Tupels/Dictionary zurück!

+1

Yup. Ich stimme zu. Genau das passiert. – vanguard69

Verwandte Themen