From a97e50c5e6afe0ce2a8fb2ca27c88e57611b0053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=9B=E4=B8=9E=E5=AE=8F?= Date: Tue, 23 Jun 2015 14:08:12 +0800 Subject: [PATCH] [1.8.x] Fixed #25016 -- Reallowed non-ASCII values for ForeignKey.related_name on Python 3. Backport of d3e12c901777697b7bf08b25e2dd46f0b951db8c from master --- django/db/models/fields/related.py | 16 ++++++++++++---- docs/releases/1.8.3.txt | 3 +++ docs/spelling_wordlist | 1 + .../invalid_models_tests/test_relative_fields.py | 11 +++++++++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 2f06d4d008..c0680eea81 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -122,10 +122,18 @@ class RelatedField(Field): import re import keyword related_name = self.rel.related_name - - is_valid_id = (related_name and re.match('^[a-zA-Z_][a-zA-Z0-9_]*$', related_name) - and not keyword.iskeyword(related_name)) - if related_name and not (is_valid_id or related_name.endswith('+')): + if not related_name: + return [] + is_valid_id = True + if keyword.iskeyword(related_name): + is_valid_id = False + if six.PY3: + if not related_name.isidentifier(): + is_valid_id = False + else: + if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*\Z', related_name): + is_valid_id = False + if not (is_valid_id or related_name.endswith('+')): return [ checks.Error( "The name '%s' is invalid related_name for field %s.%s" % diff --git a/docs/releases/1.8.3.txt b/docs/releases/1.8.3.txt index 38bcaf5374..512d6ff7c7 100644 --- a/docs/releases/1.8.3.txt +++ b/docs/releases/1.8.3.txt @@ -82,3 +82,6 @@ Bugfixes * Fixed a regression when deleting a model through the admin that has a ``GenericRelation`` with a ``related_query_name`` (:ticket:`24940`). + +* Reallowed non-ASCII values for ``ForeignKey.related_name`` on Python 3 by + fixing the false positive system check (:ticket:`25016`). diff --git a/docs/spelling_wordlist b/docs/spelling_wordlist index 04442b5b37..60c9726791 100644 --- a/docs/spelling_wordlist +++ b/docs/spelling_wordlist @@ -511,6 +511,7 @@ Quickstart quoteless Radziej rc +reallowed rebase rebased rebasing diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py index b6ac3de722..5d174d0c9b 100644 --- a/tests/invalid_models_tests/test_relative_fields.py +++ b/tests/invalid_models_tests/test_relative_fields.py @@ -5,6 +5,7 @@ from django.core.checks import Error, Warning as DjangoWarning from django.db import models from django.test.testcases import skipIfDBFeature from django.test.utils import override_settings +from django.utils import six from .base import IsolatedModelsTestCase @@ -559,9 +560,12 @@ class RelativeFieldTests(IsolatedModelsTestCase): 'contains_%s_whitespace' % whitespace, 'ends_with_with_illegal_non_alphanumeric_%s' % illegal_non_alphanumeric, 'ends_with_whitespace_%s' % whitespace, - # Python's keyword - 'with', + 'with', # a Python keyword + 'related_name\n', ] + # Python 2 crashes on non-ASCII strings. + if six.PY3: + invalid_related_names.append(',') class Parent(models.Model): pass @@ -600,6 +604,9 @@ class RelativeFieldTests(IsolatedModelsTestCase): '_+', '+', ] + # Python 2 crashes on non-ASCII strings. + if six.PY3: + related_names.extend(['試', '試驗+']) class Parent(models.Model): pass