Loading django/db/models/fields/__init__.py +15 −1 Original line number Diff line number Diff line Loading @@ -1509,6 +1509,12 @@ class FilePathField(Field): del kwargs["max_length"] return name, path, args, kwargs def get_prep_value(self, value): value = super(FilePathField, self).get_prep_value(value) if value is None: return None return six.text_type(value) def formfield(self, **kwargs): defaults = { 'path': self.path, Loading Loading @@ -1642,6 +1648,12 @@ class IPAddressField(Field): del kwargs['max_length'] return name, path, args, kwargs def get_prep_value(self, value): value = super(IPAddressField, self).get_prep_value(value) if value is None: return None return six.text_type(value) def get_internal_type(self): return "IPAddressField" Loading Loading @@ -1711,12 +1723,14 @@ class GenericIPAddressField(Field): def get_prep_value(self, value): value = super(GenericIPAddressField, self).get_prep_value(value) if value is None: return None if value and ':' in value: try: return clean_ipv6_address(value, self.unpack_ipv4) except exceptions.ValidationError: pass return value return six.text_type(value) def formfield(self, **kwargs): defaults = { Loading docs/howto/custom-model-fields.txt +11 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,17 @@ For example:: return ''.join([''.join(l) for l in (value.north, value.east, value.south, value.west)]) .. warning:: If your custom field uses the ``CHAR``, ``VARCHAR`` or ``TEXT`` types for MySQL, you must make sure that :meth:`.get_prep_value` always returns a string type. MySQL performs flexible and unexpected matching when a query is performed on these types and the provided value is an integer, which can cause queries to include unexpected objects in their results. This problem cannot occur if you always return a string type from :meth:`.get_prep_value`. Converting query values to database values ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Loading docs/ref/databases.txt +16 −0 Original line number Diff line number Diff line Loading @@ -507,6 +507,22 @@ MySQL does not support the ``NOWAIT`` option to the ``SELECT ... FOR UPDATE`` statement. If ``select_for_update()`` is used with ``nowait=True`` then a ``DatabaseError`` will be raised. Automatic typecasting can cause unexpected results -------------------------------------------------- When performing a query on a string type, but with an integer value, MySQL will coerce the types of all values in the table to an integer before performing the comparison. If your table contains the values ``'abc'``, ``'def'`` and you query for ``WHERE mycolumn=0``, both rows will match. Similarly, ``WHERE mycolumn=1`` will match the value ``'abc1'``. Therefore, string type fields included in Django will always cast the value to a string before using it in a query. If you implement custom model fields that inherit from :class:`~django.db.models.Field` directly, are overriding :meth:`~django.db.models.Field.get_prep_value`, or use :meth:`extra() <django.db.models.query.QuerySet.extra>` or :meth:`raw() <django.db.models.Manager.raw>`, you should ensure that you perform the appropriate typecasting. .. _sqlite-notes: SQLite notes Loading docs/ref/models/querysets.txt +10 −0 Original line number Diff line number Diff line Loading @@ -1189,6 +1189,16 @@ of the arguments is required, but you should use at least one of them. Entry.objects.extra(where=['headline=%s'], params=['Lennon']) .. warning:: If you are performing queries on MySQL, note that MySQL's silent type coercion may cause unexpected results when mixing types. If you query on a string type column, but with an integer value, MySQL will coerce the types of all values in the table to an integer before performing the comparison. For example, if your table contains the values ``'abc'``, ``'def'`` and you query for ``WHERE mycolumn=0``, both rows will match. To prevent this, perform the correct typecasting before using the value in a query. defer ~~~~~ Loading docs/topics/db/sql.txt +10 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,16 @@ options that make it very powerful. database, but does nothing to enforce that. If the query does not return rows, a (possibly cryptic) error will result. .. warning:: If you are performing queries on MySQL, note that MySQL's silent type coercion may cause unexpected results when mixing types. If you query on a string type column, but with an integer value, MySQL will coerce the types of all values in the table to an integer before performing the comparison. For example, if your table contains the values ``'abc'``, ``'def'`` and you query for ``WHERE mycolumn=0``, both rows will match. To prevent this, perform the correct typecasting before using the value in a query. Mapping query fields to model fields ------------------------------------ Loading Loading
django/db/models/fields/__init__.py +15 −1 Original line number Diff line number Diff line Loading @@ -1509,6 +1509,12 @@ class FilePathField(Field): del kwargs["max_length"] return name, path, args, kwargs def get_prep_value(self, value): value = super(FilePathField, self).get_prep_value(value) if value is None: return None return six.text_type(value) def formfield(self, **kwargs): defaults = { 'path': self.path, Loading Loading @@ -1642,6 +1648,12 @@ class IPAddressField(Field): del kwargs['max_length'] return name, path, args, kwargs def get_prep_value(self, value): value = super(IPAddressField, self).get_prep_value(value) if value is None: return None return six.text_type(value) def get_internal_type(self): return "IPAddressField" Loading Loading @@ -1711,12 +1723,14 @@ class GenericIPAddressField(Field): def get_prep_value(self, value): value = super(GenericIPAddressField, self).get_prep_value(value) if value is None: return None if value and ':' in value: try: return clean_ipv6_address(value, self.unpack_ipv4) except exceptions.ValidationError: pass return value return six.text_type(value) def formfield(self, **kwargs): defaults = { Loading
docs/howto/custom-model-fields.txt +11 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,17 @@ For example:: return ''.join([''.join(l) for l in (value.north, value.east, value.south, value.west)]) .. warning:: If your custom field uses the ``CHAR``, ``VARCHAR`` or ``TEXT`` types for MySQL, you must make sure that :meth:`.get_prep_value` always returns a string type. MySQL performs flexible and unexpected matching when a query is performed on these types and the provided value is an integer, which can cause queries to include unexpected objects in their results. This problem cannot occur if you always return a string type from :meth:`.get_prep_value`. Converting query values to database values ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Loading
docs/ref/databases.txt +16 −0 Original line number Diff line number Diff line Loading @@ -507,6 +507,22 @@ MySQL does not support the ``NOWAIT`` option to the ``SELECT ... FOR UPDATE`` statement. If ``select_for_update()`` is used with ``nowait=True`` then a ``DatabaseError`` will be raised. Automatic typecasting can cause unexpected results -------------------------------------------------- When performing a query on a string type, but with an integer value, MySQL will coerce the types of all values in the table to an integer before performing the comparison. If your table contains the values ``'abc'``, ``'def'`` and you query for ``WHERE mycolumn=0``, both rows will match. Similarly, ``WHERE mycolumn=1`` will match the value ``'abc1'``. Therefore, string type fields included in Django will always cast the value to a string before using it in a query. If you implement custom model fields that inherit from :class:`~django.db.models.Field` directly, are overriding :meth:`~django.db.models.Field.get_prep_value`, or use :meth:`extra() <django.db.models.query.QuerySet.extra>` or :meth:`raw() <django.db.models.Manager.raw>`, you should ensure that you perform the appropriate typecasting. .. _sqlite-notes: SQLite notes Loading
docs/ref/models/querysets.txt +10 −0 Original line number Diff line number Diff line Loading @@ -1189,6 +1189,16 @@ of the arguments is required, but you should use at least one of them. Entry.objects.extra(where=['headline=%s'], params=['Lennon']) .. warning:: If you are performing queries on MySQL, note that MySQL's silent type coercion may cause unexpected results when mixing types. If you query on a string type column, but with an integer value, MySQL will coerce the types of all values in the table to an integer before performing the comparison. For example, if your table contains the values ``'abc'``, ``'def'`` and you query for ``WHERE mycolumn=0``, both rows will match. To prevent this, perform the correct typecasting before using the value in a query. defer ~~~~~ Loading
docs/topics/db/sql.txt +10 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,16 @@ options that make it very powerful. database, but does nothing to enforce that. If the query does not return rows, a (possibly cryptic) error will result. .. warning:: If you are performing queries on MySQL, note that MySQL's silent type coercion may cause unexpected results when mixing types. If you query on a string type column, but with an integer value, MySQL will coerce the types of all values in the table to an integer before performing the comparison. For example, if your table contains the values ``'abc'``, ``'def'`` and you query for ``WHERE mycolumn=0``, both rows will match. To prevent this, perform the correct typecasting before using the value in a query. Mapping query fields to model fields ------------------------------------ Loading