Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#27259 closed Bug (invalid)

ManyToOneRel.name uses relatemodelname instead of relatedmodelname_set

Reported by: Maxim Syabro Owned by: nobody
Component: Database layer (models, ORM) Version: 1.10
Severity: Normal 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 (last modified by Maxim Syabro)

F.e.

class MainModel(models.Model):
pass

class RelatedModel(models.Model):
main = models.ForeignKey(MainModel)

ManyToOneRel.name should be relatedmodel_set, not
relatedmodel

>>> from testmodels.models import MainModel
>>> fieldname = MainModel._meta.get_fields()[0].name
>>> print getattr(MainModel, fieldname, None)
None
>>> print getattr(MainModel, fieldname + '_set', None)
object at 0x103dc1510>}}}

Change History (8)

comment:1 by Tim Graham, 8 years ago

I'm not sure if the proposal is correct. You can use get_accessor_name() to retrieve relatedmodel_set. If you provide a patch that shows how to fix this as your propose and doesn't break any tests, that might confirm whether or not the idea is correct.

comment:2 by Tim Graham, 8 years ago

Resolution: invalid
Status: newclosed

The relevant attribute is ForeignObjectRel.name which is an alias for related_query_name().

comment:3 by Maxim Syabro, 8 years ago

Tim, what if someone will have this situation:

class MainModel(models.Model):
    relatedmodel = IntegerField()

class RelatedModel(models.Model):
    main = models.ForeignKey(MainModel)

Turns out ReverseManyToOneDescriptor will replace original field. So I think it's ambiguous a little bit. Don't you think?

from .models import MainModel
for i, field in enumerate(MainModel._meta.get_fields()):
    fieldname = field.name
    print i, fieldname
    print getattr(MainModel, fieldname, None)
    print getattr(MainModel, fieldname + '_set', None)
    print

will give this output

0 relatedmodel
None
<django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x1076db950>

1 id
None
None

2 relatedmodel
None
<django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor object at 0x1076db950>
Last edited 8 years ago by Maxim Syabro (previous) (diff)

comment:4 by Maxim Syabro, 8 years ago

Description: modified (diff)

Okay, I missed this error

ERRORS:
testmodels.RelatedModel.main: (fields.E303) Reverse query name for 'RelatedModel.main' clashes with field name 'MainModel.relatedmodel'.
	HINT: Rename field 'MainModel.relatedmodel', or add/change a related_name argument to the definition for field 'RelatedModel.main'.

And I still have this questions:

  1. Why does it clash?
  2. Why related model have two names: 'relatedmodel' and 'relatedmodel_set' if we can use only second one?
  3. Why name property can't return 'relatedmodel_set' to avoid stuff above?

comment:5 by Tim Graham, 8 years ago

I can't answer the questions offhand. I'd suggest trying to develop a patch making the change you suggest and then looking at the test failures if you want to understand how Django works.

comment:6 by Maxim Syabro, 8 years ago

Description: modified (diff)

comment:7 by Maxim Syabro, 8 years ago

Description: modified (diff)

comment:8 by Maxim Syabro, 8 years ago

Okay, will do. Thanks

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