| 2817 | |
| 2818 | |
| 2819 | class UUIDField(Field): |
| 2820 | default_error_messages = { |
| 2821 | "invalid": _("“%(value)s” is not a valid UUID."), |
| 2822 | } |
| 2823 | description = _("Universally unique identifier") |
| 2824 | empty_strings_allowed = False |
| 2825 | |
| 2826 | def __init__(self, verbose_name=None, **kwargs): |
| 2827 | kwargs["max_length"] = 32 |
| 2828 | super().__init__(verbose_name, **kwargs) |
| 2829 | |
| 2830 | def deconstruct(self): |
| 2831 | name, path, args, kwargs = super().deconstruct() |
| 2832 | del kwargs["max_length"] |
| 2833 | return name, path, args, kwargs |
| 2834 | |
| 2835 | def get_internal_type(self): |
| 2836 | return "UUIDField" |
| 2837 | |
| 2838 | def get_prep_value(self, value): |
| 2839 | value = super().get_prep_value(value) |
| 2840 | return self.to_python(value) |
| 2841 | |
| 2842 | def get_db_prep_value(self, value, connection, prepared=False): |
| 2843 | if value is None: |
| 2844 | return None |
| 2845 | if not prepared and not isinstance(value, uuid.UUID): |
| 2846 | value = self.to_python(value) |
| 2847 | |
| 2848 | if connection.features.has_native_uuid_field: |
| 2849 | return value |
| 2850 | return value.hex |
| 2851 | |
| 2852 | def to_python(self, value): |
| 2853 | if value is not None and not isinstance(value, uuid.UUID): |
| 2854 | input_form = "int" if isinstance(value, int) else "hex" |
| 2855 | try: |
| 2856 | return uuid.UUID(**{input_form: value}) |
| 2857 | except (AttributeError, ValueError): |
| 2858 | raise exceptions.ValidationError( |
| 2859 | self.error_messages["invalid"], |
| 2860 | code="invalid", |
| 2861 | params={"value": value}, |
| 2862 | ) |
| 2863 | return value |
| 2864 | |
| 2865 | def formfield(self, **kwargs): |
| 2866 | return super().formfield( |
| 2867 | **{ |
| 2868 | "form_class": forms.UUIDField, |
| 2869 | **kwargs, |
| 2870 | } |
| 2871 | ) |
| 2872 | |
| 2873 | |
| 2874 | class AutoFieldMixin: |
no outgoing calls