Opened 15 years ago

Closed 14 years ago

#9638 closed (fixed)

Add %(app_label)s to the related_name format string for abstract models

Reported by: lakin@… Owned by: anonymous
Component: Core (Other) Version: 1.0
Severity: Keywords:
Cc: alexey.rudy@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Reference: be-careful-with-related-name.

Emphasis mine:

To work around this problem, when you are using related_name in an abstract base class (only), part of the name should be the string '%(class)s'. This is replaced by the lower-cased name of the child class that the field is used in. Since each class has a different name, each related name will end up being different.

This simply isn't true. The class name will be unique within the particular app, but it's very much possible to have two different apps which define a model with the same name: content.image vs security.image

I'm suggesting we add another parameter to that format string: %(app_label)s

Attachments (2)

app_label.patch (663 bytes ) - added by lakin@… 15 years ago.
Patch allowing app_label to be used.
app_label.2.patch (7.2 KB ) - added by lakin@… 15 years ago.
New patch with tests and documentation updates

Download all attachments as: .zip

Change History (8)

by lakin@…, 15 years ago

Attachment: app_label.patch added

Patch allowing app_label to be used.

comment:1 by Malcolm Tredinnick, 15 years ago

Needs documentation: set
Needs tests: set
Patch needs improvement: set
Triage Stage: UnreviewedAccepted

This is a good idea. The patch needs to include tests and a documentation update. The existing tests for this sort of feature are in tests/model_inheritance/tests/ and something new can be added there.

comment:2 by lakin@…, 15 years ago

Needs documentation: unset
Needs tests: unset
Owner: changed from nobody to anonymous
Patch needs improvement: unset
Status: newassigned

Here is an updated patch that adds tests and documentation for the feature. I ran the tests with an sqlite database and they all passed. I also ran them on a mysql database (the only other database that I happened to have installed) and I got some failures:

lakin@lawrence:~/Projects/django/trunk/tests$ python runtests.py --settings mysql_settings
/home/lakin/Projects/django/trunk/tests/regressiontests/templates/loaders.py:14: UserWarning: Module _mysql was already imported from /var/lib/python-support/python2.5/_mysql.so, but /var/lib/python-support/python2.5 is being added to sys.path
  import pkg_resources
/home/lakin/Projects/django/trunk/django/db/backends/mysql/base.py:83: Warning: Incorrect string value: '\xE6\x9E\x97\xE5\x8E\x9F...' for column 'headline' at row 1
  return self.cursor.execute(query, args)
/home/lakin/Projects/django/trunk/django/db/backends/mysql/base.py:83: Warning: Incorrect datetime value: '2005%' for column 'pub_date' at row 1
  return self.cursor.execute(query, args)
/home/lakin/Projects/django/trunk/django/db/backends/mysql/base.py:83: Warning: Incorrect string value: '\xE6\x88\x91\xE9\x9A\xBB...' for column 'file' at row 1
  return self.cursor.execute(query, args)
======================================================================
FAIL: Doctest: modeltests.serializers.models.__test__.API_TESTS
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/lakin/Projects/django/trunk/django/test/_doctest.py", line 2180, in runTest
    raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for modeltests.serializers.models.__test__.API_TESTS
  File "/home/lakin/Projects/django/trunk/tests/modeltests/serializers/models.py", line unknown line number, in API_TESTS

----------------------------------------------------------------------
File "/home/lakin/Projects/django/trunk/tests/modeltests/serializers/models.py", line ?, in modeltests.serializers.models.__test__.API_TESTS
Failed example:
    ac.save(); mv.save()
Exception raised:
    Traceback (most recent call last):
      File "/home/lakin/Projects/django/trunk/django/test/_doctest.py", line 1267, in __run
        compileflags, 1) in test.globs
      File "<doctest modeltests.serializers.models.__test__.API_TESTS[52]>", line 1, in <module>
        ac.save(); mv.save()
      File "/home/lakin/Projects/django/trunk/django/db/models/base.py", line 311, in save
        self.save_base(force_insert=force_insert, force_update=force_update)
      File "/home/lakin/Projects/django/trunk/django/db/models/base.py", line 358, in save_base
        manager.filter(pk=pk_val).extra(select={'a': 1}).values('a').order_by())):
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 191, in __nonzero__
        iter(self).next()
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 185, in _result_iter
        self._fill_cache()
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 618, in _fill_cache
        self._result_cache.append(self._iter.next())
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 659, in iterator
        for row in self.query.results_iter():
      File "/home/lakin/Projects/django/trunk/django/db/models/sql/query.py", line 206, in results_iter
        for rows in self.execute_sql(MULTI):
      File "/home/lakin/Projects/django/trunk/django/db/models/sql/query.py", line 1734, in execute_sql
        cursor.execute(sql, params)
      File "/home/lakin/Projects/django/trunk/django/db/backends/mysql/base.py", line 83, in execute
        return self.cursor.execute(query, args)
      File "/var/lib/python-support/python2.5/MySQLdb/cursors.py", line 166, in execute
        self.errorhandler(self, exc, value)
      File "/var/lib/python-support/python2.5/MySQLdb/connections.py", line 35, in defaulterrorhandler
        raise errorclass, errorvalue
    OperationalError: (1267, "Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='")
----------------------------------------------------------------------
File "/home/lakin/Projects/django/trunk/tests/modeltests/serializers/models.py", line ?, in modeltests.serializers.models.__test__.API_TESTS
Failed example:
    print serializers.serialize("json", [mv])
Expected:
    [{"pk": 1, "model": "serializers.movie", "fields": {"actor": "Za\u017c\u00f3\u0142\u0107", "title": "G\u0119\u015bl\u0105 ja\u017a\u0144"}}]
Got:
    [{"pk": null, "model": "serializers.movie", "fields": {"actor": "Za\u017c\u00f3\u0142\u0107", "title": "G\u0119\u015bl\u0105 ja\u017a\u0144"}}]


======================================================================
FAIL: Doctest: modeltests.basic.models.__test__.API_TESTS
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/lakin/Projects/django/trunk/django/test/_doctest.py", line 2180, in runTest
    raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for modeltests.basic.models.__test__.API_TESTS
  File "/home/lakin/Projects/django/trunk/tests/modeltests/basic/models.py", line unknown line number, in API_TESTS

----------------------------------------------------------------------
File "/home/lakin/Projects/django/trunk/tests/modeltests/basic/models.py", line ?, in modeltests.basic.models.__test__.API_TESTS
Failed example:
    Article.objects.get(pk=a.id).headline
Expected:
    u'\u6797\u539f \u3081\u3050\u307f'
Got:
    u'?? ???'


======================================================================
FAIL: Doctest: modeltests.custom_pk.models.__test__.API_TESTS
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/lakin/Projects/django/trunk/django/test/_doctest.py", line 2180, in runTest
    raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for modeltests.custom_pk.models.__test__.API_TESTS
  File "/home/lakin/Projects/django/trunk/tests/modeltests/custom_pk/models.py", line unknown line number, in API_TESTS

----------------------------------------------------------------------
File "/home/lakin/Projects/django/trunk/tests/modeltests/custom_pk/models.py", line ?, in modeltests.custom_pk.models.__test__.API_TESTS
Failed example:
    bus.save()
Exception raised:
    Traceback (most recent call last):
      File "/home/lakin/Projects/django/trunk/django/test/_doctest.py", line 1267, in __run
        compileflags, 1) in test.globs
      File "<doctest modeltests.custom_pk.models.__test__.API_TESTS[34]>", line 1, in <module>
        bus.save()
      File "/home/lakin/Projects/django/trunk/django/db/models/base.py", line 311, in save
        self.save_base(force_insert=force_insert, force_update=force_update)
      File "/home/lakin/Projects/django/trunk/django/db/models/base.py", line 358, in save_base
        manager.filter(pk=pk_val).extra(select={'a': 1}).values('a').order_by())):
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 191, in __nonzero__
        iter(self).next()
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 185, in _result_iter
        self._fill_cache()
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 618, in _fill_cache
        self._result_cache.append(self._iter.next())
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 659, in iterator
        for row in self.query.results_iter():
      File "/home/lakin/Projects/django/trunk/django/db/models/sql/query.py", line 206, in results_iter
        for rows in self.execute_sql(MULTI):
      File "/home/lakin/Projects/django/trunk/django/db/models/sql/query.py", line 1734, in execute_sql
        cursor.execute(sql, params)
      File "/home/lakin/Projects/django/trunk/django/db/backends/mysql/base.py", line 83, in execute
        return self.cursor.execute(query, args)
      File "/var/lib/python-support/python2.5/MySQLdb/cursors.py", line 166, in execute
        self.errorhandler(self, exc, value)
      File "/var/lib/python-support/python2.5/MySQLdb/connections.py", line 35, in defaulterrorhandler
        raise errorclass, errorvalue
    OperationalError: (1267, "Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='")


======================================================================
FAIL: Doctest: regressiontests.string_lookup.models.__test__.API_TESTS
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/lakin/Projects/django/trunk/django/test/_doctest.py", line 2180, in runTest
    raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for regressiontests.string_lookup.models.__test__.API_TESTS
  File "/home/lakin/Projects/django/trunk/tests/regressiontests/string_lookup/models.py", line unknown line number, in API_TESTS

----------------------------------------------------------------------
File "/home/lakin/Projects/django/trunk/tests/regressiontests/string_lookup/models.py", line ?, in regressiontests.string_lookup.models.__test__.API_TESTS
Failed example:
    Foo.objects.get(friend__contains=u'\xe7')
Exception raised:
    Traceback (most recent call last):
      File "/home/lakin/Projects/django/trunk/django/test/_doctest.py", line 1267, in __run
        compileflags, 1) in test.globs
      File "<doctest regressiontests.string_lookup.models.__test__.API_TESTS[18]>", line 1, in <module>
        Foo.objects.get(friend__contains=u'\xe7')
      File "/home/lakin/Projects/django/trunk/django/db/models/manager.py", line 93, in get
        return self.get_query_set().get(*args, **kwargs)
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 309, in get
        % self.model._meta.object_name)
    DoesNotExist: Foo matching query does not exist.
----------------------------------------------------------------------
File "/home/lakin/Projects/django/trunk/tests/regressiontests/string_lookup/models.py", line ?, in regressiontests.string_lookup.models.__test__.API_TESTS
Failed example:
    Foo.objects.get(friend__contains='\xc3\xa7')
Exception raised:
    Traceback (most recent call last):
      File "/home/lakin/Projects/django/trunk/django/test/_doctest.py", line 1267, in __run
        compileflags, 1) in test.globs
      File "<doctest regressiontests.string_lookup.models.__test__.API_TESTS[19]>", line 1, in <module>
        Foo.objects.get(friend__contains='\xc3\xa7')
      File "/home/lakin/Projects/django/trunk/django/db/models/manager.py", line 93, in get
        return self.get_query_set().get(*args, **kwargs)
      File "/home/lakin/Projects/django/trunk/django/db/models/query.py", line 309, in get
        % self.model._meta.object_name)
    DoesNotExist: Foo matching query does not exist.


----------------------------------------------------------------------
Ran 548 tests in 1034.511s

FAILED (failures=4)

However, they don't seem to be related to my patch. I ran just the tests that I touched and they pass just fine so I'm assuming there are other issues related to mysql -

lakin@lawrence:~/Projects/django/trunk/tests$ python runtests.py --settings mysql_settings model_inheritance model_inheritance_same_model_name
----------------------------------------------------------------------
Ran 2 tests in 0.056s

OK

by lakin@…, 15 years ago

Attachment: app_label.2.patch added

New patch with tests and documentation updates

comment:3 by anonymous, 15 years ago

Cc: alexey.rudy@… added
Has patch: unset

comment:4 by anonymous, 15 years ago

Has patch: set

comment:5 by Jacob, 15 years ago

Triage Stage: AcceptedReady for checkin

comment:6 by Jannis Leidel, 14 years ago

Resolution: fixed
Status: assignedclosed

(In [12139]) Fixed #9638 - Added %(app_label)s to the related_name format string for abstract models.

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