| 2522 | |
| 2523 | |
| 2524 | class TextField(Field): |
| 2525 | description = _("Text") |
| 2526 | |
| 2527 | def __init__(self, *args, db_collation=None, **kwargs): |
| 2528 | super().__init__(*args, **kwargs) |
| 2529 | self.db_collation = db_collation |
| 2530 | |
| 2531 | def check(self, **kwargs): |
| 2532 | databases = kwargs.get("databases") or [] |
| 2533 | return [ |
| 2534 | *super().check(**kwargs), |
| 2535 | *self._check_db_collation(databases), |
| 2536 | ] |
| 2537 | |
| 2538 | def _check_db_collation(self, databases): |
| 2539 | errors = [] |
| 2540 | for db in databases: |
| 2541 | if not router.allow_migrate_model(db, self.model): |
| 2542 | continue |
| 2543 | connection = connections[db] |
| 2544 | if not ( |
| 2545 | self.db_collation is None |
| 2546 | or "supports_collation_on_textfield" |
| 2547 | in self.model._meta.required_db_features |
| 2548 | or connection.features.supports_collation_on_textfield |
| 2549 | ): |
| 2550 | errors.append( |
| 2551 | checks.Error( |
| 2552 | "%s does not support a database collation on " |
| 2553 | "TextFields." % connection.display_name, |
| 2554 | obj=self, |
| 2555 | id="fields.E190", |
| 2556 | ), |
| 2557 | ) |
| 2558 | return errors |
| 2559 | |
| 2560 | def db_parameters(self, connection): |
| 2561 | db_params = super().db_parameters(connection) |
| 2562 | db_params["collation"] = self.db_collation |
| 2563 | return db_params |
| 2564 | |
| 2565 | def get_internal_type(self): |
| 2566 | return "TextField" |
| 2567 | |
| 2568 | def to_python(self, value): |
| 2569 | if isinstance(value, str) or value is None: |
| 2570 | return value |
| 2571 | return str(value) |
| 2572 | |
| 2573 | def get_prep_value(self, value): |
| 2574 | value = super().get_prep_value(value) |
| 2575 | return self.to_python(value) |
| 2576 | |
| 2577 | def formfield(self, **kwargs): |
| 2578 | # Passing max_length to forms.CharField means that the value's length |
| 2579 | # will be validated twice. This is considered acceptable since we want |
| 2580 | # the value in the form field (to pass into widget for example). |
| 2581 | return super().formfield( |
no outgoing calls