2015-07-10 19 views
5

Ecco la mia models.py:TypeError: int() argomento deve essere una stringa o un numero, non 'Modello 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 

sto cercando di riempire la mia base di dati da un file Excel utilizzando xlrd modulo python. Ecco la mia 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() 

Ora, quando faccio funzionare lo scritto populate_db.py, l'uscita sul terminale legge: "Problema Aggiunta di posizione al menu.". Vedo che il problema esiste qui nello script populate_db: m.location.add (l) Ma questo set di query è in linea con la sintassi dato qui: https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/

Dopo aver rimosso il try/except, la mia legge traceback :

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

Si prega di spiegare cosa sta succedendo qui. E come aggiungere correttamente un valore a ManyToManyField tramite un set di query.

Possibile duplicato: Django Error: TypeError: int() argument must be a string or a number, not 'BuildsTable' Ma mi piacerebbe comunque sapere la risposta nel mio caso poiché sto utilizzando un ManyToManyField.

completa 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

Mostrare il traceback completo. Se togli il try/eccetto qui, mi aspetterei di vedere un errore su una tupla, perché 'get_or_create' restituisce' (instance, created) '. –

+0

Sì totalmente, aggiornato. – vanguard69

+0

** l = (, False) ** Questo è l'output di * get_or_create * – vanguard69

risposta

4

Per aggiungere un valore a un ManyToManyField, è necessario aggiungere gli oggetti facendoli passare come argomenti.

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

Ciò aggiungerà gli oggetti specificati al set di oggetti correlato.

È possibile chiamare il add() come di seguito:

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

Nel tuo caso, è necessario fare:

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

, è necessario accedere al instance per indice 0 come get_or_create restituisce un tupla (instance, created). Quindi passare questo instance al metodo add().

Nota:
Utilizzando add() con una relazione molti-a-molti non chiamare qualsiasi .save() per ogni oggetto, ma piuttosto creare le relazioni con .bulk_create().

+0

Questo è esattamente ciò che sto facendo. Non funziona. – vanguard69

+0

Stai facendo 'm.location.add (int (value_list [6]))'. Cos'è 'value_list [6]'? È l'oggetto di posizione –

+1

Questa istruzione è un commento. Non è quello che sto facendo. D'altra parte sto provando questo: 'm.location.add (l)' dove 'l = Location.objects.get_or_create (location_name = sq)' – vanguard69

2

Capisco che Rahul Gupta abbia già risposto a questo.Ma a un livello più teorico credo che questo sia quello che è successo quando si utilizza get_or_create qui:

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

Si restituisce una tupla, e quindi si deve chiamare il suo primo elemento modificandolo a:

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

Che restituisce solo l'elemento indice della tupla/dizionario!

+1

Sì. Sono d'accordo. Questo è esattamente ciò che sta accadendo. – vanguard69

Problemi correlati