django S3 - trim imagefield filename but not the url path

空扰寡人 提交于 2019-12-08 15:41:34

问题


this is a followup to my question here: ImageField / FileField Django form Currently unable to trim the path to filename

In my Django app, there is an imagefield uploaded to S3 After trim the imagefile path name, the image is not accessible because the url is trimmed. How can I trim the display but don't trim the path?

I manage to trim the display showing the filename like this

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)

this is the output:

https://imgur.com/a/M42Mz <-- display correct
https://bucketname.s3.amazonaws.com/media/certiport_logo.png <-- invalid url

If I dont trim it:

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)

this is the output:

https://imgur.com/a/rGi8f <-- display incorrect
https://bucketname.s3.amazonaws.com/media/company_logo/15/certiport_logo.png <--valid url

my goal is to:

display: certiport_logo.png
url: https://bucketname.s3.amazonaws.com/media/company_logo/15/certiport_logo.png

How can I achieve this ?


回答1:


The url property of a FileField/ImageField is dynamic: it depends on the name attribute just as str() does at the time it is called. Instead, let's write to something besides name and change the template to use it instead:

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

And for the template (modified and pretty printed from django source)

{% 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:


In your case I suggest JSONField instead of ImageField. On that way you in your can have:

obj.my_image_field = {'display': 'certiport_logo.png', 'url': 'your_S3_url'}
obj.save()

class example:

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)


来源:https://stackoverflow.com/questions/48314365/django-s3-trim-imagefield-filename-but-not-the-url-path

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!