#36886 closed New feature (wontfix)
URLField max_length cannot take advantage of supports_unlimited_charfield in DB backend
| Reported by: | Joel D Sleppy | Owned by: | Joel D Sleppy |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 6.0 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | yes |
| Needs tests: | yes | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
When using a DB backend that supports_unlimited_charfield (postgres, sqlite), a CharField can omit max_length and allow arbitrarily long values in the database. However URLField, which inherits from CharField, forces the developer to pick a maximum length. For example, this model class:
class Thing(models.Model): chars = models.CharField() url = models.URLField()
Creates this table in postgres:
Table "public.app_thing" Column | Type | Collation | Nullable | Default --------+------------------------+-----------+----------+---------------------------------- id | bigint | | not null | generated by default as identity chars | character varying | | not null | url | character varying(200) | | not null |
And trying to set url = models.URLField(max_length=None) does not get recognized as a change by makemigrations.
URLs can get quite long and it's an inconvenience to pick a maximum length (and to defensively code against the possibility of it being violated). I'd like to work on this improvement myself if there's any appetite for it.
Possible changes:
- For backwards compatibility, continue to default
max_lengthto200but allow specifyingNoneto have an unbounded field. - Break backwards compatibility, changing behavior to match that of
CharField.
Change History (3)
comment:1 by , 3 weeks ago
| Needs documentation: | set |
|---|---|
| Needs tests: | set |
comment:2 by , 3 weeks ago
| Resolution: | → wontfix |
|---|---|
| Status: | assigned → closed |
| Type: | Uncategorized → New feature |
comment:3 by , 3 weeks ago
Cheers Natalia, thanks for the response. I can't say I understand fully, but I'll keep building my intuition on these things.
Hello Joel! Thank you for your ticket. I think I understand where you are coming from, but Django provides general purpose, conservative primitives.
URLFieldis not just a thin alias forCharField; it is a higher level abstraction with semantic expectations, including validation and reasonable defaults. Requiring an explicitmax_lengthis part of that contract.While URL length limits are not formally standardized, URLs do need practical bounds. Allowing unbounded URL storage meaningfully increases risk surface. Extremely long URLs are a known vector for denial of service and resource exhaustion issues across layers (application, logging, middleware, and more), and multiple historical CVEs across frameworks and servers have been rooted in unbounded or insufficiently constrained string inputs.
The existence of
supports_unlimited_charfieldat the database backend level does not imply that all higher level field types should opt into unbounded storage.CharFieldis intentionally low level.URLFieldintentionally is not. From an API design perspective, allowingmax_length=NoneforURLFieldwould blur the distinction betweenCharFieldandURLField, weaken Django's defensive defaults, and introduce subtle backwards compatibility and security review concerns for limited practical gain. Developers who genuinely need unbounded URL-like strings can already model that explicitly usingCharFieldwith specific validators.Given these considerations, the requirement for an explicit maximum length on URLField is intentional and appropriate, even on backends that support unlimited character fields.