Django S3 - обрезать имя файла изображения, но не путь URL
это продолжение моего вопроса здесь: Форма Django ImageField/FileField В настоящее время не может обрезать путь к имени файла
В моем приложении Django есть поле изображения, загруженное на S3
После обрезания пути к файлу изображения изображение становится недоступным, поскольку URL-адрес обрезается. Как я могу обрезать дисплей, но не обрезать путь?
Мне удается обрезать дисплей, показывая имя файла, как это
class CustomClearableFileInput(ClearableFileInput):
def get_context(self, name, value, attrs):
logging.debug("%s",name)
logging.debug("%s",value)
value.name = path.basename(value.name)
context = super().get_context(name, value, attrs)
return context
class CompanySettingEdit(forms.ModelForm):
company_logo = forms.ImageField(widget=CustomClearableFileInput)
это вывод:
https://imgur.com/a/M42Mz <-- display correct
https://bucketname.s3.amazonaws.com/media/certiport_logo.png <-- invalid url
Если я не урежу это:
class CustomClearableFileInput(ClearableFileInput):
def get_context(self, name, value, attrs):
logging.debug("%s",name)
logging.debug("%s",value)
# value.name = path.basename(value.name) <-- remove this
context = super().get_context(name, value, attrs)
return context
class CompanySettingEdit(forms.ModelForm):
company_logo = forms.ImageField(widget=CustomClearableFileInput)
это вывод:
https://imgur.com/a/rGi8f <-- display incorrect
https://bucketname.s3.amazonaws.com/media/company_logo/15/certiport_logo.png <--valid url
моя цель состоит в том, чтобы:
display: certiport_logo.png
url: https://bucketname.s3.amazonaws.com/media/company_logo/15/certiport_logo.png
Как мне этого добиться?
Ответы
Ответ 1
Свойство url
для FileField/ImageField является динамическим: оно зависит от атрибута name
так же, как str()
во время его вызова. Вместо этого позвольте написать что-то кроме name
и измените шаблон, чтобы использовать его вместо этого:
class CustomClearableFileInput(ClearableFileInput):
template_name = 'path/to/clearable_file_input.html'
# less confusing place than get_context...
def format_value(self, value):
if self.is_initial(value):
value.basename = path.basename(value.name)
return value
И для шаблона (модифицированного и довольно напечатанного из источника django)
{% if widget.is_initial %}
{{ widget.initial_text }}:
<a href="{{ widget.value.url }}">
{{ widget.value.basename }} {# <== CHANGE #}
</a>
{% if not widget.required %}
<input type="checkbox" name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}" />
<label for="{{ widget.checkbox_id }}">{{ widget.clear_checkbox_label }}</label>
{% endif %}
<br /> {{ widget.input_text }}:
{% endif %}
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %} />
Ответ 2
В вашем случае я предлагаю JSONField вместо ImageField. На этом пути вы можете иметь:
obj.my_image_field = {'display': 'certiport_logo.png', 'url': 'your_S3_url'}
obj.save()
пример класса:
class MyModel(models.Model):
my_image_field = JSONField()
def get_image_display(self):
return self.my_image_field.get('display', None)
def get_image_url(self):
return self.my_image_field.get('url', None)