Code

Opened 6 years ago

Closed 5 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: UI/UX:

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@… 6 years ago.
Patch allowing app_label to be used.
app_label.2.patch (7.2 KB) - added by lakin@… 6 years ago.
New patch with tests and documentation updates

Download all attachments as: .zip

Change History (8)

Changed 6 years ago by lakin@…

Patch allowing app_label to be used.

comment:1 Changed 6 years ago by mtredinnick

  • Needs documentation set
  • Needs tests set
  • Patch needs improvement set
  • Triage Stage changed from Unreviewed to Accepted

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 Changed 6 years ago by lakin@…

  • Needs documentation unset
  • Needs tests unset
  • Owner changed from nobody to anonymous
  • Patch needs improvement unset
  • Status changed from new to assigned

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

Changed 6 years ago by lakin@…

New patch with tests and documentation updates

comment:3 Changed 5 years ago by anonymous

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

comment:4 Changed 5 years ago by anonymous

  • Has patch set

comment:5 Changed 5 years ago by jacob

  • Triage Stage changed from Accepted to Ready for checkin

comment:6 Changed 5 years ago by jezdez

  • Resolution set to fixed
  • Status changed from assigned to closed

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

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.