﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
1281	Options.get_field() fails to check one_to_one_field, causes bogus validation error	python@…	Adrian Holovaty	"I have a simple model which described 4 different bugs, one of which has a ticket with patch.
I have a patch for the last bug (labeled 'Bug3') which this ticket is for. I will file the others once I get a chance.
The problem is that Options objects which are constructed from Model classes which inherit from other Model classes may have a 'one_to_one_field' which is not in its 'fields' attribute. This can cause a bogus app validation error

meta_bug.py
{{{
#!python
from django.core import meta

# Create your models here.
class A(meta.Model):
    name = meta.SlugField(blank=False, unique=True)
    class META:
        admin = meta.Admin()
    def __repr__(self):
        return self.name

class B(meta.Model):
    a = meta.OneToOneField(A)
    ## Bug1: NEED to add another Field or Admin B edits will crash!
    class META:
        order_with_respect_to = 'a' # Ticket #930 (defect) workaround
        admin = meta.Admin()
    def __repr__(self):
        return ""B - "" + repr(self.get_a())

class C(meta.Model):
    b = meta.ForeignKey(B,edit_inline=meta.TABULAR,
                        to_field='a_id') # Bug2: to_field defaults to 'a' which
                                         # is wrong and causes Admin B Add's
                                         # to fail.
    data = meta.SlugField(core=True)
    def __repr__(self):
        return self.data

class _B(meta.Model):
    ap = meta.OneToOneField(A)
    class META:
        order_with_respect_to = 'a' # Ticket #930 (defect) workaround

class BP(_B):
    something = meta.SlugField() ## prevent Bug1 to show Bug3...

class CP(meta.Model):
    bp = meta.ForeignKey(BP,edit_inline=meta.TABULAR,
                         to_field='ap_id') # Bug3: Bug2 workaround no longer
                                           # works due to early model validation
                                           # error... Patch included.
    data = meta.SlugField(core=True)
    def __repr__(self):
        return self.data
}}}

This gives the following validation error:
{{{
Mya@miyu /c/django/projects/pycon
$ python manage.py install meta_bug
Traceback (most recent call last):
  File ""manage.py"", line 11, in ?
    execute_manager(settings)
  File ""c:/python24/lib/site-packages/django-0.91-py2.4.egg/django/core/management.py"", line 990, in execute_manager
    execute_from_command_line(action_mapping)
  File ""c:/python24/lib/site-packages/django-0.91-py2.4.egg/django/core/management.py"", line 965, in execute_from_command_line
    output = action_mapping[action](mod)
  File ""c:/python24/lib/site-packages/django-0.91-py2.4.egg/django/core/management.py"", line 405, in install
    sql_list = get_sql_all(mod)
  File ""c:/python24/lib/site-packages/django-0.91-py2.4.egg/django/core/management.py"", line 268, in get_sql_all
    return get_sql_create(mod) + get_sql_initial_data(mod)
  File ""c:/python24/lib/site-packages/django-0.91-py2.4.egg/django/core/management.py"", line 70, in get_sql_create
    rel_field = f.rel.get_related_field()
  File ""c:/python24/lib/site-packages/django-0.91-py2.4.egg/django/core/meta/fields.py"", line 846, in get_related_field
    return self.to.get_field(self.field_name)
  File ""c:/python24/lib/site-packages/django-0.91-py2.4.egg/django/core/meta/__init__.py"", line 463, in get_field
    raise FieldDoesNotExist, ""name=%s"" % name
django.core.meta.FieldDoesNotExist: name=a_id
}}}

Here is a patch which fixes this bug:
{{{
#!diff
--- django.core.meta.__init__.py.orig   2006-01-26 15:48:45.000000000 -0500
+++ django/core/meta/__init__.py 2006-01-26 15:50:28.000000000 -0500
@@ -460,6 +460,10 @@
         for f in to_search:
             if f.name == name:
                 return f
+        if (hasattr(self, 'one_to_one_field') and
+            self.one_to_one_field is not None and
+            self.one_to_one_field.name == name):
+            return self.one_to_one_field
         raise FieldDoesNotExist, ""name=%s"" % name

     def get_order_sql(self, table_prefix=''):
}}}
"	defect	closed	Metasystem	0.91	normal	invalid	FieldDoesNotExist Options get_field to_field		Unreviewed	0	0	0	0	0	0
