1
0
mirror of https://github.com/django/django.git synced 2025-10-31 01:25:32 +00:00

Fixed #14094 -- Added support for unlimited CharField on PostgreSQL.

Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
This commit is contained in:
Adrian Torres
2022-11-10 19:31:31 +01:00
committed by Mariusz Felisiak
parent 78f163a4fb
commit 7eee1dca42
12 changed files with 78 additions and 15 deletions

View File

@@ -339,7 +339,8 @@ class Command(BaseCommand):
# Add max_length for all CharFields.
if field_type == "CharField" and row.display_size:
field_params["max_length"] = int(row.display_size)
if (size := int(row.display_size)) and size > 0:
field_params["max_length"] = size
if field_type in {"CharField", "TextField"} and row.collation:
field_params["db_collation"] = row.collation

View File

@@ -345,6 +345,9 @@ class BaseDatabaseFeatures:
# Set to (exception, message) if null characters in text are disallowed.
prohibits_null_characters_in_text_exception = None
# Does the backend support unlimited character columns?
supports_unlimited_charfield = False
# Collation names for use by the Django test suite.
test_collations = {
"ci": None, # Case-insensitive.

View File

@@ -80,6 +80,12 @@ from .operations import DatabaseOperations # NOQA isort:skip
from .schema import DatabaseSchemaEditor # NOQA isort:skip
def _get_varchar_column(data):
if data["max_length"] is None:
return "varchar"
return "varchar(%(max_length)s)" % data
class DatabaseWrapper(BaseDatabaseWrapper):
vendor = "postgresql"
display_name = "PostgreSQL"
@@ -92,7 +98,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
"BigAutoField": "bigint",
"BinaryField": "bytea",
"BooleanField": "boolean",
"CharField": "varchar(%(max_length)s)",
"CharField": _get_varchar_column,
"DateField": "date",
"DateTimeField": "timestamp with time zone",
"DecimalField": "numeric(%(max_digits)s, %(decimal_places)s)",

View File

@@ -110,3 +110,4 @@ class DatabaseFeatures(BaseDatabaseFeatures):
has_bit_xor = property(operator.attrgetter("is_postgresql_14"))
supports_covering_spgist_indexes = property(operator.attrgetter("is_postgresql_14"))
supports_unlimited_charfield = True

View File

@@ -817,9 +817,14 @@ class Field(RegisterLookupMixin):
# exactly which wacky database column type you want to use.
data = self.db_type_parameters(connection)
try:
return connection.data_types[self.get_internal_type()] % data
column_type = connection.data_types[self.get_internal_type()]
except KeyError:
return None
else:
# column_type is either a single-parameter function or a string.
if callable(column_type):
return column_type(data)
return column_type % data
def rel_db_type(self, connection):
"""
@@ -1130,14 +1135,19 @@ class BooleanField(Field):
class CharField(Field):
description = _("String (up to %(max_length)s)")
def __init__(self, *args, db_collation=None, **kwargs):
super().__init__(*args, **kwargs)
self.db_collation = db_collation
if self.max_length is not None:
self.validators.append(validators.MaxLengthValidator(self.max_length))
@property
def description(self):
if self.max_length is not None:
return _("String (up to %(max_length)s)")
else:
return _("String (unlimited)")
def check(self, **kwargs):
databases = kwargs.get("databases") or []
return [
@@ -1148,6 +1158,12 @@ class CharField(Field):
def _check_max_length_attribute(self, **kwargs):
if self.max_length is None:
if (
connection.features.supports_unlimited_charfield
or "supports_unlimited_charfield"
in self.model._meta.required_db_features
):
return []
return [
checks.Error(
"CharFields must define a 'max_length' attribute.",