2012-06-19 15 views
5

Używam django 1.3.1 i satchmo 0.9.2. Użyłem domyślnego modelu dostarczanego z Satchmo o nazwie Contact. Stworzyłem aplikację satchmo_mod i plik admin.py.fk_name 'user' nie jest ForeignKey do <klasa '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 

następnie utworzyć admin.py:

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

Następnie uruchom:

python manage.py runserver 

Przejdź do:

127.0.0.1:8000 

ten błąd:

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

widzę ten błąd w ślad stosu i zacząć iść na zwiedzanie:

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

Krótko mówiąc, kiedy model kontaktowy zostanie zarejestrowany z powrotem, to wszystko znajduje się opcje _meta nie są regenerowane jak daleko jak mogę powiedzieć. Patrz 'manage.py shell' sesji poniżej:

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: zrobiłem fix zalecane przez Maccesch. Ale wydaje się po wyrejestrowanie obiektu kontaktu i ponowną rejestracją go z nowym inline, że zrobił coś złamać Zinnia:

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

UPDATE: chcą rozpocząć nowe pytanie, nie był pewien.

Jest to kod modelu i 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) 

Więc UserTaxExempt ma ForeignKey do Użytkownika, więc nie powinno ta praca jest w porządku? Działa na stronie użytkownika, więc nie rozumiem, dlaczego nie działałoby na stronie Kontakt.

+2

Co dokładnie chcesz zrobić, a nie, jak to działa? Pojawia się tylko komunikat o błędzie, gdy dzwonisz do wewnętrznych funkcji Django i nie mam pojęcia, na co patrzę w pozostałej części tego wyjścia konsoli. – Elliott

+0

Próbuję zarejestrować prosty modelAdmin. Wyjąłem modeladmin i po prostu wyrejestrowałem model, ponownie go zarejestrowałem i znowu dał mi błąd! Wyjście z konsoli to przejście do funkcji sprawdzania poprawności używanej do sprawdzania kluczy obcych i sprawdzania wszystkich wartości/etc. Wygląda na to, że _meta.get_parents_list() nie jest generowane poprawnie. Po wyjęciu sprawdzania klucza obcego w rzeczywistych plikach django (bad, wiem, ale testowanie go, aby zobaczyć, czy działa), strona działa poprawnie. Jest to oczywiście ważny klucz obcy. Czy satchmo robi jakieś dziwne zmiany w django, które to przesłaniają? – Codygman

+1

Elliott powiedział, że nadal nie jest jasne, co tak naprawdę próbujesz zrobić. Model "Kontakt" w pytaniu jest tym z 'satchmo_store.contact.models'? A co masz na myśli mówiąc o zarejestrowaniu prostego ModelAdmin? Zaktualizuj swoje pytanie i podaj więcej kontekstu. – Maccesch

Odpowiedz

4

Problem wydaje się być w twoim UserTaxExemptInline. Nie zakładać, jak to wygląda, ale myślę, że to wygląda tak:

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

podczas gdy powinno to wyglądać tak:

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

Próbowałem tego, ale skończyło się na tym, że zrywałem blog z cynią. – Codygman

+1

To nadal jest właściwe rozwiązanie. Powinieneś zadać nowe pytanie na temat tego problemu z cynią? – Maccesch

1

Zobacz _get_foreign_key w django/forms/models.py.

opis _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. 

A teraz za wyjątkiem:

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

ja domyślam się, że nie masz poprawnie ustawiony pola lub relacje w modelu.

Czytałem gdzieś ktoś rozwiązanie tego problemu poprzez dodanie pass do ich klasy tak:

class Whatever(x.x): 
     pass 
Powiązane problemy