2012-06-19 2 views
5

Estoy usando django 1.3.1 y satchmo 0.9.2. Utilicé el modelo predeterminado que se envía con Satchmo llamado Contacto. Creé una aplicación satchmo_mod y un archivo admin.py.fk_name 'user' no es una ForeignKey para <clase '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 

luego crear admin.py:

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

Luego ejecutar:

python manage.py runserver 

Ir a:

127.0.0.1:8000 

sale este error:

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

veo este error en el seguimiento de la pila y empezar a ir a explorar:

/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> 

Para resumir, cuando el modelo de contacto se registró hacia atrás, toda ella es opciones _meta no están siendo regenerados en la medida de como yo puedo decir Ver la sesión 'manage.py shell' a continuación:

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'> 

ACTUALIZACIÓN: hice la corrección recomendada por Maccesch. Pero parece que después de anular el registro del objeto de contacto y volver a registrar con la nueva línea, que hizo algo para romper Zinnia:

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

ACTUALIZACIÓN: que desee empezar una nueva pregunta, no estaba segura.

Este es el código para el modelo y 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) 

Así UserTaxExempt tiene un ForeignKey al usuario, por lo que no debe este trabajo bien? Funciona en la página de usuario, por lo que no entiendo por qué no funcionaría en la página de contacto.

+2

¿Qué es exactamente estás tratando de hacer, y cómo no está funcionando? La única vez que veo que aparece el error es cuando llamas funciones internas de Django, y no tengo idea de lo que estoy viendo en el resto de la salida de la consola. – Elliott

+0

Estoy tratando de registrar un ModelAdmin simple. Saqué el modeladmin y simplemente no registré el modelo, lo reinscribí y me dio el error nuevamente. La salida de la consola me permite acceder a la función de validación utilizada para validar claves externas y observar todos los valores/etc. Parece que _meta.get_parents_list() no se está generando correctamente. Cuando obtengo la validación de la clave externa en los archivos django reales (mal, lo sé pero lo pruebo para ver si funciona), el sitio funciona bien. Obviamente es una clave foránea válida. ¿Sátchmo hace algunas ediciones extrañas para django que estropea esto? – Codygman

+1

Como dijo Elliott, todavía no está claro lo que realmente está tratando de hacer. El modelo 'Contact' en su pregunta es este de' satchmo_store.contact.models'? ¿Y qué quiere decir con registrar un ModelAdmin simple? Por favor, actualice su pregunta y proporcione más contexto. – Maccesch

Respuesta

4

Parece que el problema está en su UserTaxExemptInline. Que no publique la forma que se parece pero supongo que se ve así:

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

mientras que debería tener este aspecto:

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

Intenté esto, pero terminó rompiendo el blog zinnia. – Codygman

+1

Todavía es la solución correcta. ¿Tal vez deberías hacer una nueva pregunta sobre ese problema de zinnia? – Maccesch

1

Ver _get_foreign_key en django/forms/models.py.

Descripción _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. 

Y ahora para la excepción:

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

estoy adivinando que no ha configurado los campos o las relaciones en el modelo correctamente.

He leído en alguna parte de alguien resolver este problema mediante la adición de pass a su clase, así:

class Whatever(x.x): 
     pass 
Cuestiones relacionadas