[Django] #21053: Missing related fields

11 views
Skip to first unread message

Django

unread,
Sep 6, 2013, 12:32:42 PM9/6/13
to django-...@googlegroups.com
#21053: Missing related fields
----------------------------------------------+--------------------
Reporter: joshua.fialkoff@… | Owner: nobody
Type: Uncategorized | Status: new
Component: Database layer (models, ORM) | Version: 1.5
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------------------+--------------------
I have an application with these 4 models (amongst others):

{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!python
class Note(CaseModel):
name = models.CharField(max_length=100)
notes = models.TextField(blank=True)

@property
def shortened_notes(self):
if len(self.notes) > 100:
return self.notes[:100] + '...'
return self.notes


class Document(CaseModel):
name = models.CharField(max_length=100)
upc = models.CharField(max_length=100, verbose_name="UPC")
file = models.FileField(upload_to="prvate/documents/")
notes = models.TextField(blank=True)

@property
def shortened_notes(self):
if len(self.notes) > 100:
return self.notes[:100] + '...'
return self.notes

class NoteAttachTo(AttachTo):
class Meta:
verbose_name = 'Attach To'
verbose_name_plural = 'Attach to'
unique_together = ('note', 'attach_to_type', 'attach_to_id')

note = models.ForeignKey(Note)


class DocumentAttachTo(AttachTo):
class Meta:
verbose_name = 'Attach To'
verbose_name_plural = 'Attach to'
unique_together = ('document', 'attach_to_type', 'attach_to_id')

document = models.ForeignKey(Document)


}}}
}}}

`AttachTo` and `CaseModel` are abstract base models with fields that are
common to their subclasses. Note that `Note` and `Document` are
essentially copies of each other. However, while `Note` has the related
field `noteattachto`, `Document` does not have `documentattachto`:

{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!python
In [1]: from cases.models import Note, Document

In [2]: Note._meta.get_all_field_names()
Out[2]: ['case', u'id', 'name', 'noteattachto', 'notes']

In [3]: Document._meta.get_all_field_names()
Out[3]: ['case', 'file', u'id', 'name', 'notes', 'upc']
}}}
}}}

I tried to debug this a bit and added a `print` statement in
db/models/options.py - `_fill_related_objects_cache`:

{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!python
#### Starting on line 438 of db/models/options.py
# Collect also objects which are in relation to some proxy
child/parent of self.
proxy_cache = cache.copy()
for klass in get_models(include_auto_created=True,
only_installed=False):
print(self.db_table + ': ' + klass.__name__)
if not klass._meta.swapped:
for f in klass._meta.local_fields:
...
}}}
}}}


The relevant output is below. Note that, when the model cache is being
built for `Document`, neither `DocumentAttachTo` or `NoteAttachTo` are
available. Those models do, however, become available immediately after
"Validating models..." is printed to the screen. At this point, I'm not
really sure what's going on.

{{{
django_content_type: ContentType
django_content_type: Permission
django_content_type: Group_permissions
django_content_type: Group
django_content_type: User_groups
django_content_type: User_user_permissions
django_content_type: User
django_content_type: Site
django_content_type: Case
django_content_type: Debtor
django_content_type: Claim_debtors
django_content_type: Claim
django_content_type: Note
django_content_type: Document
django_content_type: PartyRole
django_content_type: Party
django_content_type: Contact
django_content_type: CourtProceeding
django_content_type: Session
django_content_type: LogEntry
django_content_type: MigrationHistory
cases_claim: ContentType
cases_claim: Permission
cases_claim: Group_permissions
cases_claim: Group
cases_claim: User_groups
cases_claim: User_user_permissions
cases_claim: User
cases_claim: Site
cases_claim: Case
cases_claim: Debtor
cases_claim: Claim_debtors
cases_claim: Claim
cases_claim: Note
cases_claim: Document
cases_claim: PartyRole
cases_claim: Party
cases_claim: Contact
cases_claim: CourtProceeding
cases_claim: Session
cases_claim: LogEntry
cases_claim: MigrationHistory
cases_document: ContentType
cases_document: Permission
cases_document: Group_permissions
cases_document: Group
cases_document: User_groups
cases_document: User_user_permissions
cases_document: User
cases_document: Site
cases_document: Case
cases_document: Debtor
cases_document: Claim_debtors
cases_document: Claim
cases_document: Note
cases_document: Document
cases_document: PartyRole
cases_document: Party
cases_document: Contact
cases_document: CourtProceeding
cases_document: Session
cases_document: LogEntry
cases_document: MigrationHistory
Validating models...

auth_permission: ContentType
auth_permission: Permission
auth_permission: Group_permissions
auth_permission: Group
auth_permission: User_groups
auth_permission: User_user_permissions
auth_permission: User
auth_permission: Site
auth_permission: Case
auth_permission: Debtor
auth_permission: Claim_debtors
auth_permission: Claim
auth_permission: Note
auth_permission: Document
auth_permission: PartyRole
auth_permission: Party
auth_permission: Contact
auth_permission: CourtProceeding
auth_permission: NoteAttachTo
auth_permission: DocumentAttachTo
auth_permission: Session
auth_permission: LogEntry
auth_permission: MigrationHistory
cases_note: ContentType
cases_note: Permission
cases_note: Group_permissions
cases_note: Group
cases_note: User_groups
cases_note: User_user_permissions
cases_note: User
cases_note: Site
cases_note: Case
cases_note: Debtor
cases_note: Claim_debtors
cases_note: Claim
cases_note: Note
cases_note: Document
cases_note: PartyRole
cases_note: Party
cases_note: Contact
cases_note: CourtProceeding
cases_note: NoteAttachTo
cases_note: DocumentAttachTo
cases_note: Session
cases_note: LogEntry
cases_note: MigrationHistory
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/21053>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Sep 7, 2013, 2:17:31 AM9/7/13
to django-...@googlegroups.com
#21053: Missing related fields
-------------------------------------+-------------------------------------
Reporter: joshua.fialkoff@… | Owner: grue
Type: Uncategorized | Status: assigned
Component: Database layer | Version: 1.5
(models, ORM) | Resolution:
Severity: Normal | Triage Stage:
Keywords: | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by grue):

* status: new => assigned
* needs_better_patch: => 0
* owner: nobody => grue
* needs_tests: => 0
* needs_docs: => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/21053#comment:1>

Django

unread,
Sep 7, 2013, 2:04:25 PM9/7/13
to django-...@googlegroups.com
#21053: Missing related fields
-------------------------------------+-------------------------------------
Reporter: joshua.fialkoff@… | Owner: grue
Type: Uncategorized | Status: closed

Component: Database layer | Version: 1.5
(models, ORM) | Resolution:
Severity: Normal | worksforme
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0

| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by grue):

* status: assigned => closed
* resolution: => worksforme


Comment:

I've been unable to replicate this. Could you provide any additional
information or test cases that would allow me to reproduce this bug?

models.py:
{{{
from django.db import models


class CaseModel(models.Model):
case = models.CharField(max_length=100)

class Meta:
abstract = True


class Note(CaseModel):
name = models.CharField(max_length=100)
notes = models.TextField(blank=True)

@property
def shortened_notes(self):
if len(self.notes) > 100:
return self.notes[:100] + '...'
return self.notes


class Document(CaseModel):
name = models.CharField(max_length=100)
upc = models.CharField(max_length=100, verbose_name="UPC")
file = models.FileField(upload_to="prvate/documents/")
notes = models.TextField(blank=True)

@property
def shortened_notes(self):
if len(self.notes) > 100:
return self.notes[:100] + '...'
return self.notes


class AttachTo(models.Model):
class Meta:
abstract = True


class NoteAttachTo(AttachTo):
class Meta:
verbose_name = 'Attach To'
verbose_name_plural = 'Attach to'
unique_together = ('note', 'attach_to_type', 'attach_to_id')

note = models.ForeignKey(Note)


class DocumentAttachTo(AttachTo):
class Meta:
verbose_name = 'Attach To'
verbose_name_plural = 'Attach to'
unique_together = ('document', 'attach_to_type', 'attach_to_id')

document = models.ForeignKey(Document)

}}}

console output:
{{{


In [1]: from cases.models import Note, Document

In [2]: Note._meta.get_all_field_names()
Out[2]: ['case', u'id', 'name', 'noteattachto', 'notes']

In [3]: Document._meta.get_all_field_names()
Out[3]: ['case', 'documentattachto', 'file', u'id', 'name', 'notes',
'upc']
}}}

python version: Python 2.7.3

pip freeze:
{{{
Django==1.5.2
argparse==1.2.1
ipython==1.0.0
wsgiref==0.1.2
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/21053#comment:2>

Reply all
Reply to author
Forward
0 new messages