2012-06-19 4 views
5

Ich verwende django 1.3.1 und satchmo 0.9.2. Ich habe das Standardmodell verwendet, das mit Satchmo geliefert wird und Contact genannt wird. Ich habe eine satchmo_mod-App und eine admin.py-Datei erstellt.fk_name 'user' ist kein ForeignKey für <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 

dann erstellen admin.py:

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

ich dann laufen:

python manage.py runserver 

Gehe zu:

127.0.0.1:8000 

diesen Fehler:

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

ich diesen Fehler in der Stack-Trace zu sehen und zu gehen beginnen zu entdecken:

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

Lange Rede kurzer Sinn, wenn der Kontakt Modell zurück registriert wird, all seine _meta Optionen sind nicht so weit regeneriert wie ich es sagen kann. Siehe 'manage.py Shell' Sitzung unter:

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: Ich habe das Update von Maccesch empfohlen. Aber es scheint, nach dem Kontakt Objekt enfernen, und es mit dem neuen Inline-Neuregistrierung, es etwas tat Zinnia zu brechen:

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

UPDATE: Könnte eine neue Frage beginnen soll, war nicht sicher.

Dies ist der Code für das Modell und 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) 

So UserTaxExempt eine foreignkey auf Benutzer hat, so sollte nicht das funktioniert gut? Es funktioniert auf der Benutzerseite, weshalb ich nicht verstehe, warum es auf der Kontaktseite nicht funktioniert.

+2

Was Sie zu tun genau das versuchen, und wie ist es nicht funktioniert? Das einzige Mal, dass ich den Fehler sehe, ist, wenn Sie Django-interne Funktionen aufrufen, und ich habe keine Ahnung, was ich im Rest dieser Konsolenausgabe ansehe. – Elliott

+0

Ich versuche ein einfaches ModelAdmin zu registrieren. Ich nahm das Modeladmin heraus und meldete das Modell einfach ab, registrierte es erneut und es gab mir wieder den Fehler! Die Konsole Ausgabe ist mir graben auf die Validierungsfunktion zur Validierung von Fremdschlüsseln und die Betrachtung aller Werte/etc. Es scheint, dass _meta.get_parents_list() nicht korrekt generiert wird. Wenn ich die Fremdschlüssel-Validierung in den tatsächlichen Django-Dateien (schlecht, ich weiß, aber testet es um zu sehen, ob funktioniert) herausnehmen, funktioniert die Website gut. Es ist offensichtlich ein gültiger Fremdschlüssel. Hat Satchmo einige seltsame Änderungen am Django vorgenommen, die das vermasseln? – Codygman

+1

Wie Elliott sagte, ist es immer noch nicht klar, was Sie wirklich versuchen zu tun. Das 'Kontakt'-Modell in Ihrer Frage ist das aus' satchmo_store.contact.models'? Und was meinst du mit einem einfachen ModelAdmin registrieren? Bitte aktualisieren Sie Ihre Frage und geben Sie mehr Kontext. – Maccesch

Antwort

4

Das Problem scheint in Ihrem UserTaxExemptInline zu sein. Sie haben nicht schreiben, wie das aussieht, aber ich denke, es sieht wie folgt aus:

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

während es sollte wie folgt aussehen:

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

Ich habe das versucht, aber es endete nur den Zinnia Blog zu brechen. – Codygman

+1

Es ist immer noch die richtige Lösung. Sie sollten vielleicht eine neue Frage zu diesem Zinnienproblem stellen? – Maccesch

1

Siehe _get_foreign_key in django/forms/models.py.

_get_foreign_key Beschreibung:

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. 

Und jetzt Ausnahme:

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

Ich vermute, dass Sie die Felder oder Beziehungen in Ihrem Modell nicht richtig eingerichtet haben.

Ich habe irgendwo über jemand die Lösung dieses Problems lesen von pass ihrer Klasse wie so hinzufügen:

class Whatever(x.x): 
     pass