Opened 19 years ago

Closed 18 years ago

Last modified 17 years ago

#527 closed defect (fixed)

OneToOne relations are broken since new model style released

Reported by: mordaha Owned by: Adrian Holovaty
Component: Metasystem Version:
Severity: critical Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

#================================================================================
# Document
#================================================================================
class Document(meta.Model):
    #MAIN FIELDS
    doc_date = meta.DateField('date')
    doc_subj = meta.CharField('subj', maxlength=250)
    doc_text = meta.TextField('text', maxlength=250, blank=True)
#================================================================================
#  Letter
#================================================================================
class Letter(meta.Model):
    #IS LETTER
    document = meta.OneToOneField(Document)
    doc_number = meta.CharField('doc number', maxlength=20)
    # from and to ForeignKeys were skipped

#================================================================================
#  Order
#================================================================================
class Order(meta.Model):
    #IS ORDER
    letter = meta.OneToOneField(Letter)
    order_date_plan = meta.DateField('order date plan')
    order_date_fakt = meta.DateField('order date fakt', blank=True, null=True)

Document can be simple or Letter, and Document that is Letter can be an Order or not.
This example works fine with old model syntax.
With a new-style model syntax any relations between Letter - Order are fail.

Document - Letter relation works fine.

>>> from django.models.main import *
>>> d = documents.get_object(pk=21)
>>> l = letters.get_object(pk=21)
>>> o = orders.get_object(pk=21)
>>> d.get_letter()
Letter 21
>>> l.get_document()
Document 21

OK
Now try Letter - Order

>>> l.get_order()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\utils\functi
onal.py", line 3, in _curried
    return args[0](*(args[1:]+moreargs), **dict(kwargs.items() + morekwargs.item
s()))
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\core\meta\__
init__.py", line 931, in method_get_related
    kwargs['%s__%s__exact' % (rel_field.name, rel_field.rel.to.pk.name)] = getat
tr(self, rel_field.rel.field_name)
AttributeError: 'Letter' object has no attribute 'document'
>>>
>>>
>>>
>>> o.get_letter()                                                              
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\utils\functi
onal.py", line 3, in _curried
    return args[0](*(args[1:]+moreargs), **dict(kwargs.items() + morekwargs.item
s()))
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\core\meta\__
init__.py", line 873, in method_get_many_to_one
    retrieved_obj = mod.get_object(**{'%s__exact' % field_with_rel.rel.field_nam
e: val})
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\utils\functi
onal.py", line 3, in _curried
    return args[0](*(args[1:]+moreargs), **dict(kwargs.items() + morekwargs.item
s()))
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\core\meta\__
init__.py", line 1083, in function_get_object
    obj_list = function_get_list(opts, klass, **kwargs)
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\core\meta\__
init__.py", line 1123, in function_get_list
    return list(function_get_iterator(opts, klass, **kwargs))
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\core\meta\__
init__.py", line 1105, in function_get_iterator
    select, sql, params = function_get_sql_clause(opts, **kwargs)
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\core\meta\__
init__.py", line 1302, in function_get_sql_clause
    tables2, join_where2, where2, params2, _ = _parse_lookup(kwargs.items(), opt
s)
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\core\meta\__
init__.py", line 1231, in _parse_lookup
    _throw_bad_kwarg_error(kwarg)
  File "C:\Python24\Lib\site-packages\django-1.0.0-py2.4.egg\django\core\meta\__
init__.py", line 1181, in _throw_bad_kwarg_error
    raise TypeError, "got unexpected keyword argument '%s'" % kwarg
TypeError: got unexpected keyword argument 'document__exact'
>>>
>>>

Change History (8)

comment:1 by Adrian Holovaty, 19 years ago

Status: newassigned

Added a unit test in [648].

comment:2 by Adrian Holovaty, 19 years ago

milestone: Version 1.0

comment:3 by plisk, 18 years ago

Any news about this issue ? Also faced it, wondering how to continue development now without it..

comment:4 by asmodai@…, 18 years ago

I am also trying to get OneToOneField() working.

This is my model:

from django.core import meta

class Kanji(meta.Model):

entry = meta.CharField(maxlength = 16)
compound = meta.BooleanField()
jouyou = meta.BooleanField()
stroke_count = meta.PositiveIntegerField()
class META:

admin = meta.Admin()

class Classification(meta.Model):

type = meta.CharField(maxlength = 64)
class META:

admin = meta.Admin()

def repr(self):

return "%s" % self.type

class Reading(meta.Model):

kanji = meta.ForeignKey(Kanji, edit_inline = meta.STACKED, num_in_admin = 1)
on = meta.CharField(blank = True, core = True, maxlength = 128)
kun = meta.CharField(blank = True, core = True, maxlength = 128)
classification = meta.OneToOneField(Classification)
synonym = meta.ForeignKey(Kanji)
antonym = meta.ForeignKey(Kanji)

class Meaning(meta.Model):

reading = meta.ForeignKey(Reading, edit_inline = meta.STACKED, num_in_admin = 1)
dutch = meta.TextField(core = True)
class META:

admin = meta.Admin()

And when opening 'add kanjis' in the admin interface I get:

Exception Type: KeyError
Exception Value: 'Field reading.0.classification not found'
Exception Location: /usr/local/lib/python2.4/site-packages/django/core/formfields.py in getitem, line 25

I think I have been doing it correctly, but I am still a beginner though.

comment:5 by Adrian Holovaty, 18 years ago

Resolution: fixed
Status: assignedclosed

(In [1313]) Fixed #527 and #768 -- Fixed longstanding bug with OneToOneFields. All unit tests now pass

comment:6 by gp.ciceri@…, 18 years ago

Resolution: fixed
Status: closedreopened

It seems I'm not able to delete() an object that has an OneToOneField. You still take errors.

File "/sw/lib/python2.4/site-packages/Django-0.90-py2.4.egg/django/core/meta/init.py", line 967, in method_get_related

kwargs% (rel_field.name, rel_field.rel.to.pk.name) = getattr(self, rel_field.rel.field_name)

AttributeError: 'Person' object has no attribute 'party'

(person is the class that has an OneToOneField that points to party id)

comment:7 by Adrian Holovaty, 18 years ago

Resolution: fixed
Status: reopenedclosed

(In [1319]) Fixed #527 -- Changed method_get_related() to use rel.get_related_field() instead of rel.field_name

comment:8 by (none), 17 years ago

milestone: Version 1.0

Milestone Version 1.0 deleted

Note: See TracTickets for help on using tickets.
Back to Top