Code

Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#16299 closed Bug (fixed)

Django model-module doesn't support unicode_literals

Reported by: martijn.bastiaan@… Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords: unicode, ForeignKey, AttributeError
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

Hello all,

When using

from __future__ import unicode_literals

in a model file, Django fails to recognize a model referenced by a string and raises a quite obscure error message:

Traceback (most recent call last):
  File "test.py", line 5, in <module>
    a = article.Article.objects.get(id=57220255)
  File "/usr/local/lib/django/django/db/models/manager.py", line 132, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/usr/local/lib/django/django/db/models/query.py", line 341, in get
    clone = self.filter(*args, **kwargs)
  File "/usr/local/lib/django/django/db/models/query.py", line 550, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/usr/local/lib/django/django/db/models/query.py", line 568, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/usr/local/lib/django/django/db/models/sql/query.py", line 1172, in add_q
    can_reuse=used_aliases, force_having=force_having)
  File "/usr/local/lib/django/django/db/models/sql/query.py", line 1060, in add_filter
    negate=negate, process_extras=process_extras)
  File "/usr/local/lib/django/django/db/models/sql/query.py", line 1226, in setup_joins
    field, model, direct, m2m = opts.get_field_by_name(name)
  File "/usr/local/lib/django/django/db/models/options.py", line 307, in get_field_by_name
    cache = self.init_name_map()
  File "/usr/local/lib/django/django/db/models/options.py", line 339, in init_name_map
    for f, model in self.get_all_related_objects_with_model():
  File "/usr/local/lib/django/django/db/models/options.py", line 371, in get_all_related_objects_with_model
    self._fill_related_objects_cache()
  File "/usr/local/lib/django/django/db/models/options.py", line 393, in _fill_related_objects_cache
    if f.rel and not isinstance(f.rel.to, str) and self == f.rel.to._meta:
AttributeError: 'unicode' object has no attribute '_meta'

Model example:

    insert_user = models.ForeignKey("models.User", db_column='insertuser_id')

    # Or without from __future__ import unicode_literals
    insert_user = models.ForeignKey(u"models.User", db_column='insertuser_id')

I've attached a patch.

Yours,
Martijn

Attachments (4)

support-for-unicode-literals.diff (1.2 KB) - added by martijn.bastiaan@… 3 years ago.
Patch
support-for-unicode-literals.2.diff (1.5 KB) - added by martijn.bastiaan@… 3 years ago.
Patch (2)
django-unicodely-named-model-field-tests.diff (2.4 KB) - added by anthonyb 3 years ago.
django-unicodely-named-model-field-tests-2.diff (2.4 KB) - added by anthonyb 3 years ago.
Updated test which doesn't cause Foreign Key errors

Download all attachments as: .zip

Change History (10)

Changed 3 years ago by martijn.bastiaan@…

Patch

comment:1 Changed 3 years ago by melinath

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

Accepted, but shouldn't the check be isinstance(obj, basestring)? Also, the patch still needs docs and tests.

Changed 3 years ago by martijn.bastiaan@…

Patch (2)

comment:2 Changed 3 years ago by martijn.bastiaan@…

shouldn't the check be isinstance(obj, basestring)?

Yes, you're correct. Fixed!


needs docs

I've added documentation to the diff. Is it sufficient?


and tests

I'm not sure where to put the unittest. Could you help me?

comment:3 Changed 3 years ago by anthonyb

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

I've attached a patch (django-unicodely-named-model-field-tests.diff) which fixes the unicode issue and adds a test, but only for foreign key names which will convert cleanly to ascii.

Names which have 'real' unicode characters in them will still fail, but these cause errors in validation.py which are much harder to catch and fix.

I've also spoken directly to Russell, and he claims that a documentation patch isn't necessary for this bug.

Changed 3 years ago by anthonyb

Changed 3 years ago by anthonyb

Updated test which doesn't cause Foreign Key errors

comment:4 Changed 3 years ago by russellm

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

In [16663]:

Fixed #16299 -- Ensure that unicode strings can be used to identify classes in ForeignKey and ManyToManyFields. Unicode strings aren't actually legal as class names, but this is an issue if you use from future import unicode_literals in your models.py file. Thanks to Martijn Bastiaan for the report, and Anthony Briggs for the final patch.

comment:5 Changed 3 years ago by russellm

In [16675]:

[1.3.X] Fixed #16299 -- Ensure that unicode strings can be used to identify classes in ForeignKey and ManyToManyFields. Unicode strings aren't actually legal as class names, but this is an issue if you use from future import unicode_literals in your models.py file. Thanks to Martijn Bastiaan for the report, and Anthony Briggs for the final patch.

Backport of r16663 from trunk.

comment:6 Changed 3 years ago by mtredinnick

In [16679]:

Added another test to confirm fix in r16663.

This is the test case from #6045, which was fixed by the above commit.
Refs #6045, #16299

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.