| 327 | }) |
| 328 | |
| 329 | def render_field(self, field, parent_style): |
| 330 | if isinstance(field._field, serializers.HiddenField): |
| 331 | return '' |
| 332 | |
| 333 | style = self.default_style[field].copy() |
| 334 | style.update(field.style) |
| 335 | if 'template_pack' not in style: |
| 336 | style['template_pack'] = parent_style.get('template_pack', self.template_pack) |
| 337 | style['renderer'] = self |
| 338 | |
| 339 | # Get a clone of the field with text-only value representation ('' if None or False). |
| 340 | field = field.as_form_field() |
| 341 | |
| 342 | if style.get('input_type') == 'datetime-local': |
| 343 | try: |
| 344 | format_ = field._field.format |
| 345 | except AttributeError: |
| 346 | format_ = api_settings.DATETIME_FORMAT |
| 347 | |
| 348 | if format_ is not None and field.value not in (None, ''): |
| 349 | # field.value is expected to be a string |
| 350 | # https://www.django-rest-framework.org/api-guide/fields/#datetimefield |
| 351 | field_value = field.value |
| 352 | if format_ == ISO_8601 and sys.version_info < (3, 11): |
| 353 | # We can drop this branch once we drop support for Python < 3.11 |
| 354 | # https://docs.python.org/3/whatsnew/3.11.html#datetime |
| 355 | field_value = field_value.rstrip('Z') |
| 356 | field.value = ( |
| 357 | datetime.datetime.fromisoformat(field_value) if format_ == ISO_8601 |
| 358 | else datetime.datetime.strptime(field_value, format_) |
| 359 | ) |
| 360 | |
| 361 | if isinstance(field.value, datetime.datetime): |
| 362 | # The format of an input type="datetime-local" is "yyyy-MM-ddThh:mm" |
| 363 | # followed by optional ":ss" or ":ss.SSS", so keep only the first three |
| 364 | # digits of milliseconds to avoid browser console error. |
| 365 | field.value = field.value.replace(tzinfo=None).isoformat(timespec="milliseconds") |
| 366 | |
| 367 | if 'template' in style: |
| 368 | template_name = style['template'] |
| 369 | else: |
| 370 | template_name = style['template_pack'].strip('/') + '/' + style['base_template'] |
| 371 | |
| 372 | template = loader.get_template(template_name) |
| 373 | context = {'field': field, 'style': style} |
| 374 | return template.render(context) |
| 375 | |
| 376 | def render(self, data, accepted_media_type=None, renderer_context=None): |
| 377 | """ |