Opened 16 years ago

Closed 16 years ago

#7149 closed (duplicate)

Multiple OneToOne Models __really__ changed/Broke in Refactor

Reported by: bo <bo.blanton@…> Owned by: nobody
Component: Core (Other) Version: dev
Severity: Keywords: OneToOneField Refactor #7173
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

It now appears that only ONE one-to-one Sub table is allowed for Models ... this, well, i imagine will break lots of other folks things for example

# a simple 2 One-To-One tables models
from django.db import models

class BaseMoo(models.Model):
	name = models.CharField(max_length = 50)
	is_moo = models.BooleanField(default = True)

class MooOne(models.Model):
	basemoo = models.OneToOneField(BaseMoo, primary_key = True)
	is_moo_one = models.BooleanField(default = True)

class MooTwo(models.Model):
	basemoo = models.OneToOneField(BaseMoo, primary_key = True)
	is_moo_two = models.BooleanField(default = True)

and run a little run the test


	b_moo = BaseMoo(name = "I Am Foo", is_moo = True)
	b_moo.save()
	
	MooOne(basemoo = b_moo, is_moo_one = True).save()
	MooTwo(basemoo = b_moo, is_moo_two = False).save()
	
	m_moo = BaseMoo.objects.get(name = "I Am Foo")
	try:
		print m_moo
		print repr(m_moo.mooone)
		print repr(m_moo.mootwo)
		print "\nMOO One", m_moo.mooone.is_moo_one,
		print "\nMOO Two", m_moo.mootwo.is_moo_two,
	except Exception, e:
		print "\nGADS!", e
	finally:
		m_moo.delete()




the scary output form that little test

BaseMoo object
<MooOne: MooOne object>
<MooOne: MooOne object>

MOO One 1 
MOO Two 
GADS! 'MooOne' object has no attribute 'is_moo_two'

As one can see the Attribute 'mootwo' is really pointing to 'mooone'.
It would be one thing if 'mootwo' as an attribute tossed an Attribute Error, but to point it at 'mooone' is really scary.
If this in fact the 'desired' effect now for OneToOnes, then really there needs to be some way (shown in the Documentation somewhere) to allow multiple OneToOnes to live on a given table ..

Change History (4)

comment:1 by oyvind, 16 years ago

Does this falls into the same category as #7125?

comment:2 by bo, 16 years ago

I do not think so, but i could be wrong. Below is the '_meta' object dump (where 'testmod' is my test module for this err)

pprint(m_moo._meta.__dict__)
{'_field_cache': ((<django.db.models.fields.AutoField object at 0x14f4430>,
                   None),
                  (<django.db.models.fields.CharField object at 0x107cb70>,
                   None),
                  (<django.db.models.fields.BooleanField object at 0x14e5970>,
                   None)),
 '_field_name_cache': [<django.db.models.fields.AutoField object at 0x14f4430>,
                       <django.db.models.fields.CharField object at 0x107cb70>,
                       <django.db.models.fields.BooleanField object at 0x14e5970>],
 '_join_cache': {},
 '_m2m_cache': {},
 '_name_map': {'id': (<django.db.models.fields.AutoField object at 0x14f4430>,
                      None,
                      True,
                      False),
               'is_moo': (<django.db.models.fields.BooleanField object at 0x14e5970>,
                          None,
                          True,
                          False),
               'mooone': (<RelatedObject: testmod:mooone related to basemoo>,
                          None,
                          False,
                          False),
               'mootwo': (<RelatedObject: testmod:mootwo related to basemoo>,
                          None,
                          False,
                          False),
               'name': (<django.db.models.fields.CharField object at 0x107cb70>,
                        None,
                        True,
                        False)},
 '_related_many_to_many_cache': {},
 '_related_objects_cache': {<RelatedObject: testmod:mooone related to basemoo>: None, <RelatedObject: testmod:mootwo related to basemoo>: None},
 'abstract': False,
 'admin': None,
 'app_label': 'testmod',
 'auto_field': <django.db.models.fields.AutoField object at 0x14f4430>,
 'db_table': 'testmod_basemoo',
 'db_tablespace': '',
 'get_latest_by': None,
 'has_auto_field': True,
 'installed': False,
 'local_fields': [<django.db.models.fields.AutoField object at 0x14f4430>,
                  <django.db.models.fields.CharField object at 0x107cb70>,
                  <django.db.models.fields.BooleanField object at 0x14e5970>],
 'local_many_to_many': [],
 'module_name': 'basemoo',
 'object_name': 'BaseMoo',
 'one_to_one_field': <django.db.models.fields.related.OneToOneField object at 0x14ff3d0>,
 'order_with_respect_to': None,
 'ordering': [],
 'parents': {},
 'permissions': [],
 'pk': <django.db.models.fields.AutoField object at 0x14f4430>,
 'unique_together': [],
 'verbose_name': 'base moo',
 'verbose_name_plural': <django.utils.functional.__proxy__ object at 0x14f43f0>}

Looking deeper into the _name_map we find

pprint(m_moo._meta._name_map['mooone'][0].__dict__)
pprint(m_moo._meta._name_map['mootwo'][0].__dict__)

{'edit_inline': False,
 'field': <django.db.models.fields.related.OneToOneField object at 0x14ff410>,
 'model': <class 'testmod.models.MooOne'>,
 'name': 'testmod:mooone',
 'opts': <Options for MooOne>,
 'parent_model': <class 'testmod.models.BaseMoo'>,
 'var_name': 'mooone'}

{'edit_inline': False,
 'field': <django.db.models.fields.related.OneToOneField object at 0x14ff5f0>,
 'model': <class 'testmod.models.MooTwo'>,
 'name': 'testmod:mootwo',
 'opts': <Options for MooTwo>,
 'parent_model': <class 'testmod.models.BaseMoo'>,
 'var_name': 'mootwo'}

everything 'looks' ok, but for some reason the attribute is broken .. since i've not dug too deep into the new Inheritance stuff (where i imagine the problem lies) i cannot say if the 2 bugs are related.

It also should be noted that the

m_moo.delete()

does NOT find the mootwo as related delete, and thus leaves it in the DB

I find this bug the most serious of issues as how else does one 'Add' data/models to another App (i.e. i want to add Birthday to a User, well, there's only one Birthday per user, and i obviously cannot add it to the contrib.auth app, so i goes in another app along with any other little things like this, and is a OneToOne).

aside from that multiple OneToOnes are terribly important for DB performance and Caching .. for example, a hit counter on an object really should be a one to one as we can still cache the 'Base' objects data, and only worry about the 'hit count' when we need it (which is usually much less then the base object). We can also update the Hitcounter Table, which will not invalidate and DB caches (aka MySql QueryCache)

comment:3 by George Vilches, 16 years ago

This looks like the problem in #7173. Does the patch attached there fix this for you? If so, we can dupe this ticket for that one.

comment:4 by bo <bo.blanton@…>, 16 years ago

Keywords: #7173 added
Resolution: duplicate
Status: newclosed

That did appear to be the issue in #7173 at least on the little test above. I'll dupe it for now unless i find other issues relating to this.

something so small to cause so much pain....

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