2012-06-19 8 views
5

Sto usando django 1.3.1 e satchmo 0.9.2. Ho usato il modello predefinito fornito con Satchmo chiamato Contact. Ho creato un'app satchmo_mod e un file admin.py.fk_name 'utente' non è un ForeignKey per <class 'satchmo_store.contact.models.Contact'>

pip install django==1.3.1 
pip install -r http://bitbucket.org/chris1610/satchmo/raw/tip/scripts/requirements.txt 
pip install satchmo 0.9.2 

django-admin.py startproject fk_test 
cd fk_test 
python manage.py startapp satchmo_mod 

quindi creare admin.py:

from satchmo_store.contact.models import Contact 
admin.site.unregister(Contact) 
admin.site.register(Contact) 

ho quindi eseguire:

python manage.py runserver 

Vai a:

127.0.0.1:8000 

Ottenere questo errore:

fk_name 'user' is not a ForeignKey to <class 'satchmo_store.contact.models.Contact'> 

vedo questo errore nella traccia dello stack e iniziare ad andare ad esplorare:

/home/cody/work/martin-instruments/virtual-envs/mi-prod-copy/lib/python2.6/site-packages/django/contrib/admin/validation.py in validate_inline 
    fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True) ... 
▼ Local vars 
Variable Value 
parent_model  
<class 'satchmo_store.contact.models.Contact'> 
cls 
<class 'satchmo_mod.admin.UserTaxExemptInline'> 
parent 
<class 'django.contrib.admin.options.ModelAdmin'> 
f 
<django.db.models.fields.related.OneToOneField object at 0x2ec2250> 

Per farla breve, quando il modello di contatto viene registrato di nuovo, tutto questo è opzioni _meta non vengono rigenerate per quanto come posso dire. Vedere la sessione 'manage.py shell' di seguito:

envs/mi2.0/mi$ ./manage.py shell 
Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) 
[GCC 4.4.5] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
(InteractiveConsole) 
>>> from satchmo_mod.admin import UserTaxExemptInline 
>>> from satchmo_mod.admin import MyContactOptions 
>>> from django.db.models.fields.related import OneToOneField 
>>> from satchmo_store.contact.models import Contact 
>>> cls = UserTaxExemptInline 
>>> parent_model = Contact 
>>> parent = MyContactOptions 
>>> from django.contrib.admin.validation import get_field 
>>> f = get_field(cls, cls.model, cls.model._meta, 'fk_name', cls.fk_name) 
>>> print f 
<django.db.models.fields.related.OneToOneField object at 0x2c358d0> 
>>> dir(f) 
['__class__', '__cmp__', '__deepcopy__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slotnames__', '__str__', '__subclasshook__', '__weakref__', '_choices', '_description', '_get_choices', '_get_flatchoices', '_get_val_from_obj', '_pk_trace', '_unique', 'attname', 'auto_created', 'auto_creation_counter', 'bind', 'blank', 'choices', 'clean', 'column', 'contribute_to_class', 'contribute_to_related_class', 'creation_counter', 'db_column', 'db_index', 'db_tablespace', 'db_type', 'default', 'default_error_messages', 'default_validators', 'description', 'do_related_class', 'editable', 'empty_strings_allowed', 'error_messages', 'flatchoices', 'formfield', 'get_attname', 'get_attname_column', 'get_cache_name', 'get_choices', 'get_choices_default', 'get_db_prep_lookup', 'get_db_prep_save', 'get_db_prep_value', 'get_default', 'get_flatchoices', 'get_internal_type', 'get_prep_lookup', 'get_prep_value', 'get_validator_unique_lookup_type', 'has_default', 'help_text', 'max_length', 'model', 'name', 'null', 'opts', 'pre_save', 'primary_key', 'rel', 'related', 'related_query_name', 'run_validators', 'save_form_data', 'serialize', 'set_attributes_from_name', 'set_attributes_from_rel', 'to_python', 'unique', 'unique_for_date', 'unique_for_month', 'unique_for_year', 'validate', 'validators', 'value_from_object', 'value_to_string', 'verbose_name'] 
>>> from django.db import models 
>>> isinstance(f, models.ForeignKey) 
True 
>>> from django.forms.models import _get_foreign_key 
>>> fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/home/cody/work/martin-instruments/virtual-envs/mi2.0/lib/python2.6/site-packages/django/forms/models.py", line 770, in _get_foreign_key 
    raise Exception("fk_name '%s' is not a ForeignKey to %s" % (fk_name, parent_model)) 
Exception: fk_name 'user' is not a ForeignKey to <class 'satchmo_store.contact.models.Contact'> 
>>> print parent_model, cls.model, cls.fk_name 
<class 'satchmo_store.contact.models.Contact'> <class 'satchmo_mod.models.UserTaxExempt'> user 
>>> fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/home/cody/work/martin-instruments/virtual-envs/mi2.0/lib/python2.6/site-packages/django/forms/models.py", line 770, in _get_foreign_key 
    raise Exception("fk_name '%s' is not a ForeignKey to %s" % (fk_name, parent_model)) 
Exception: fk_name 'user' is not a ForeignKey to <class 'satchmo_store.contact.models.Contact'> 
>>> print model 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
NameError: name 'model' is not defined 
>>> print parent_model 
<class 'satchmo_store.contact.models.Contact'> 
>>> cls.model 
<class 'satchmo_mod.models.UserTaxExempt'> 
>>> model = cls.model 
>>> opts = model._meta 
>>> fk_name 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
NameError: name 'fk_name' is not defined 
>>> fk_name = cls.fk_name 
>>> fk_name 
'user' 
>>> fks_to_parent = [f for f in opts.fields if f.name == fk_name] 
>>> print fks_to_parent 
[<django.db.models.fields.related.OneToOneField object at 0x2c358d0>] 
>>> not isinstance(fk, ForeignKey) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
NameError: name 'fk' is not defined 
>>> fk = fks_to_parent[0] 
>>> not isinstance(fk, ForeignKey) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
NameError: name 'ForeignKey' is not defined 
>>> from django.db.models import ForeignKey 
>>> not isinstance(fk, ForeignKey) 
False 
>>> len(fks_to_parent) == 1 
True 
>>> not isinstance(fk, ForeignKey) or \ 
... 768      (fk.rel.to != parent_model and 
... fk.rel.to not in parent_model._meta.get_parent_list()) 
Traceback (most recent call last): 
    File "<console>", line 3, in <module> 
TypeError: 'int' object is not callable 
>>> not isinstance(fk, ForeignKey) or (fk.rel.to != parent_model and fk.rel.to not in parent_model._meta.get_parent_list()) 
True 
>>> parent_model 
<class 'satchmo_store.contact.models.Contact'> 
>>> parent_model._meta.get_parent_list() 
set([]) 
>>> fk.rel.to 
<class 'django.contrib.auth.models.User'> 
>>> fk.rel.to != parent_model 
True 
>>> fk.rel.to not in parent_model._meta.get_parent_list() 
True 
>>> fk.rel.to 
<class 'django.contrib.auth.models.User'> 
>>> fk.rel.to == parent_model 
False 
>>> parent_model 
<class 'satchmo_store.contact.models.Contact'> 
>>> fk 
<django.db.models.fields.related.OneToOneField object at 0x2c358d0> 
>>> fk.rel.to 
<class 'django.contrib.auth.models.User'> 
>>> # User has to be not equal to Contact 
>>> # and fk.rel.to can't be in the parent model's parent list 
>>> fk.rel.to 
<class 'django.contrib.auth.models.User'> 
>>> fk.rel 
<django.db.models.fields.related.OneToOneRel object at 0x2c35990> 
>>> fk.rel.to != parent_model 
True 
>>> # OneToOneRel can't be equal to parent_model(Contact) nor can OneToOneRel be in the parent_model(Contact) parent list 
>>> Contact._meta.get_parent_list() 
set([]) 
>>> parent_model is Contact 
True 
>>> fk.rel.to in parent_model._meta.get_parent_list() 
False 
>>> fk.rel.to != parent_model 
True 
>>> (fk.rel.to != parent_model and fk.rel.to not in parent_model._meta.get_parent_list()) 
True 
>>> (fk.rel.to != parent_model and fk.rel.to not in parent_model._meta.get_parent_list()) 
True 
>>> (True and False) 
False 
>>> fk.rel.to != parent_model 
True 
>>> fk.rel.to.not in parent_model._meta.get_parent_list() 
    File "<console>", line 1 
    fk.rel.to.not in parent_model._meta.get_parent_list() 
       ^
SyntaxError: invalid syntax 
>>> fk.rel.to not in parent_model._meta.get_parent_list() 
True 
>>> fk.rel.to != parent_model 
True 
>>> fk.rel.to not in parent_model._meta.get_parent_list() 
True 
>>> fk.rel.to 
<class 'django.contrib.auth.models.User'> 
>>> parent-model 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
TypeError: unsupported operand type(s) for -: 'MediaDefiningClass' and 'ModelBase' 
>>> parent_model 
<class 'satchmo_store.contact.models.Contact'> 
>>> fk.rel.to 
<class 'django.contrib.auth.models.User'> 
>>> parent_model 
<class 'satchmo_store.contact.models.Contact'> 
>>> parent_model._meta.get_parent_list() 
set([]) 
>>> parent_model.parents 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
AttributeError: type object 'Contact' has no attribute 'parents' 
>>> parent_model.options 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
AttributeError: type object 'Contact' has no attribute 'options' 
>>> opts 
<Options for UserTaxExempt> 
>>> parent_model._meta 
<Options for Contact> 
>>> parent_model._meta.parents 
{} 
>>> User._meta.parents 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
NameError: name 'User' is not defined 
>>> from django.contrib.auth.models import User 
>>> User._meta.parents 
{} 
>>> from martin.models import CreditApplication 
>>> CreditApplication._meta.parents 
{} 
>>> User._meta.fields 
[<django.db.models.fields.AutoField object at 0x21d45d0>, <django.db.models.fields.CharField object at 0x21d2450>, <django.db.models.fields.CharField object at 0x21d25d0>, <django.db.models.fields.CharField object at 0x21d26d0>, <django.db.models.fields.EmailField object at 0x21d27d0>, <django.db.models.fields.CharField object at 0x21d2950>, <django.db.models.fields.BooleanField object at 0x21d2a90>, <django.db.models.fields.BooleanField object at 0x21d2bd0>, <django.db.models.fields.BooleanField object at 0x21d2d10>, <django.db.models.fields.DateTimeField object at 0x21d2e10>, <django.db.models.fields.DateTimeField object at 0x21d2e90>] 
>>> Contact._meta.fields 
[<django.db.models.fields.AutoField object at 0x289a510>, <django.db.models.fields.CharField object at 0x2899a90>, <django.db.models.fields.CharField object at 0x2899c10>, <django.db.models.fields.CharField object at 0x2899d10>, <django.db.models.fields.related.ForeignKey object at 0x2899dd0>, <django.db.models.fields.related.ForeignKey object at 0x2899e90>, <django.db.models.fields.related.ForeignKey object at 0x2899f90>, <django.db.models.fields.DateField object at 0x289a0d0>, <django.db.models.fields.EmailField object at 0x289a150>, <django.db.models.fields.TextField object at 0x289a2d0>, <django.db.models.fields.DateField object at 0x289a350>] 
>>> Contact._meta.fields[0] 
<django.db.models.fields.AutoField object at 0x289a510> 
>>> dir(Contact._meta.fields[0]) 
['__class__', '__cmp__', '__deepcopy__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_choices', '_description', '_get_choices', '_get_flatchoices', '_get_val_from_obj', '_unique', 'attname', 'auto_created', 'auto_creation_counter', 'bind', 'blank', 'choices', 'clean', 'column', 'contribute_to_class', 'creation_counter', 'db_column', 'db_index', 'db_tablespace', 'db_type', 'default', 'default_error_messages', 'default_validators', 'description', 'editable', 'empty_strings_allowed', 'error_messages', 'flatchoices', 'formfield', 'get_attname', 'get_attname_column', 'get_cache_name', 'get_choices', 'get_choices_default', 'get_db_prep_lookup', 'get_db_prep_save', 'get_db_prep_value', 'get_default', 'get_flatchoices', 'get_internal_type', 'get_prep_lookup', 'get_prep_value', 'get_validator_unique_lookup_type', 'has_default', 'help_text', 'max_length', 'model', 'name', 'null', 'pre_save', 'primary_key', 'rel', 'run_validators', 'save_form_data', 'serialize', 'set_attributes_from_name', 'to_python', 'unique', 'unique_for_date', 'unique_for_month', 'unique_for_year', 'validate', 'validators', 'value_from_object', 'value_to_string', 'verbose_name'] 
>>> Contact._meta.fields[0].model 
<class 'satchmo_store.contact.models.Contact'> 
>>> Contact._meta.fields[1].model 
<class 'satchmo_store.contact.models.Contact'> 

UPDATE: ho la correzione raccomandato da Maccesch. Ma sembra, dopo l'annullamento della registrazione l'oggetto contatto, ed una nuova registrazione con il nuovo in linea, ha fatto qualcosa per rompere Zinnia:

fk_name 'user' is not a ForeignKey to <class 'zinnia.models.Category'> 

UPDATE: potrebbe voler iniziare una nuova domanda, non era sicuro.

Questo è il codice per il modello e ModelAdmin:

Models.py

class UserTaxExempt(models.Model): 
    user = models.OneToOneField(_User, primary_key=True) 
    tax_exempted = models.BooleanField("No taxes would be applied to purchases") 

    class Meta: 
     verbose_name = _('Tax Exemption') 
     verbose_name_plural = _('Tax Exemption') 

    def __unicode__(self): 
     if self.tax_exempted: 
      return unicode("Purchases are exempted from taxes") 
     else: 
      return unicode("Purchases are taxed") 

admin.py

from satchmo_mod.models import ContactTaxExempt 
from satchmo_store.contact.admin import PhoneNumber_Inline, AddressBook_Inline 
from satchmo_store.contact.models import Contact 

class ContactTaxExemptInline(admin.TabularInline): 
    model = ContactTaxExempt 
    max_num = 1 
    extra = 1 
    can_delete = False 
    fk_name = "user" 

class ContactOptions(admin.ModelAdmin): 
    list_display = ('last_name', 'first_name') 
    list_filter = ['create_date'] 
    ordering = ['last_name'] 
    search_fields = ('first_name', 'last_name', 'email') 
    related_search_fields = {'user': ('username', 'first_name', 'last_name', 'em 
    related_string_functions = {'user': lambda u: u"%s (%s)" % (u.username, u.ge 
    inlines = [ContactTaxExemptInline, PhoneNumber_Inline, AddressBook_Inline] 

admin.site.unregister(Contact) 
admin.site.register(Contact, ContactOptions) 

Così UserTaxExempt ha un ForeignKey per utente, quindi non dovrebbe questo funziona bene? Funziona sulla pagina utente, quindi non capisco perché non funzionerebbe nella pagina dei contatti.

+2

Che cosa stai cercando di fare, e come non sta funzionando? L'unica volta che vedo apparire l'errore è quando chiamate le funzioni interne di Django e non ho idea di cosa sto guardando nel resto dell'output di questa console. – Elliott

+0

Sto tentando di registrare un ModelAdmin semplice. Ho tirato fuori il modeladmin e ho appena annullato la registrazione della modella, l'ho registrata nuovamente e mi ha restituito l'errore! L'output della console mi sta scavando verso il basso per la funzione di convalida utilizzata per convalidare le chiavi esterne e guardare tutti i valori/ecc. Sembra che _meta.get_parents_list() non venga generato correttamente. Quando prendo la convalida della chiave esterna nei file django effettivi (male, lo so ma testandolo per vedere se funziona), il sito funziona correttamente. È ovviamente una chiave estera valida. Satchmo fa qualche strana modifica al django che lo incasina? – Codygman

+1

Come Elliott ha detto che non è ancora chiaro cosa stai provando a fare. Il modello 'Contact' nella tua domanda è questo da' satchmo_store.contact.models'? E cosa intendi con registrare un semplice ModelAdmin? Si prega di aggiornare la tua domanda e dare più contesto. – Maccesch

risposta

4

Il problema sembra essere nel tuo UserTaxExemptInline. Non hai messaggio how che sembra, ma credo che si presenta così:

class UserTaxExemptInline(admin.TabularInline): 
    model = Contact 
    fk_name = "user" 

mentre dovrebbe assomigliare a questo:

class UserTaxExemptInline(admin.TabularInline): 
    model = User 
+0

Ho provato questo, ma è appena finito per rompere il blog zinnia. – Codygman

+1

È ancora la soluzione giusta. Dovresti forse fare una nuova domanda sul problema della zinnia? – Maccesch

1

Vedi _get_foreign_key in django/forms/models.py.

descrizione _get_foreign_key:

Finds and returns the ForeignKey from model to parent if there is one 
(returns None if can_fail is True and no such field exists). If fk_name is 
provided, assume it is the name of the ForeignKey field. Unles can_fail is 
True, an exception is raised if there is no ForeignKey from model to 
parent_model. 

E ora per l'eccezione:

if fk_name: 
     fks_to_parent = [f for f in opts.fields if f.name == fk_name] 
     if len(fks_to_parent) == 1: 
      fk = fks_to_parent[0] 
      if not isinstance(fk, ForeignKey) or \ 
        (fk.rel.to != parent_model and 
        fk.rel.to not in parent_model._meta.get_parent_list()): 
       raise Exception("fk_name '%s' is not a ForeignKey to %s" % (fk_name, parent_model)) 

sto indovinando che non avete installato correttamente i campi o le relazioni nel modello.

ho letto da qualche parte di qualcuno di risolvere il problema aggiungendo pass alla loro classe in questo modo:

class Whatever(x.x): 
     pass