5

I have a test template that allows a user to add an uploaded file image as well as the image title as a char field to the users account. This is working OK.

I am now trying to allow the user to edit the already uploaded file image and the image title details.

Is it possible to hide the image link and instead display the image in its place?

I have read the django docs, searched SO & Google and worked on and off for 2 1/2 days but I am still unable to resolve this issue.

There seems to be plenty of information of how to upload a new file image but not how to edit the already uploaded file image.

Here is my models.py code:

def _get_document_upload_location(instance, filename):
"""
Using a function instead of a lambda to make migrations happy. DO NOT remove or rename this function in the future, as it will break migrations.
@param instance: model instance that owns the FileField we're generating the upload filename for.
@param filename: Original file name assigned by django.
"""
return 'attachments/%d/%s' % (instance.user.id, uuid.uuid4())

class AttachmentDetails(models.Model, FillableModelWithLanguageVersion):
    user = models.ForeignKey(User)
    language_version = models.ForeignKey('LanguageVersion')
    attachment_document = models.FileField(upload_to=_get_document_upload_location)
    attachment_title = models.CharField(null=False, blank=False, max_length=250)
    attachment_timestamp_added = models.DateTimeField(auto_now_add=True, auto_now=False)
    attachment_timestamp_updated = models.DateTimeField(auto_now=True, auto_now_add=False)

Here is my views.py file code:

def attachment_details_edit(request, attachment_details_id):
    try:
        attachment_details = AttachmentDetails.objects.get(pk=attachment_details_id, user=request.user)
    except AttachmentDetails.DoesNotExist:
        return redirect(settings.MENU_DETAIL_LINK_ATTACHMENT_DETAILS)
    language_versions = LanguageVersion.objects.filter(user=request.user).select_related('language_version')
    available_languages = get_available_language_details(language_versions, request.user.userprofile.language_preference)
    attachment_details_num = request.user.attachmentdetails_set.count()
    language_code = attachment_details.language_version.language_code
    language_code_disabled = attachment_details.language_version.language_code_disabled
    language_preference = request.user.userprofile.language_preference
    if language_code_disabled:
        return redirect(settings.MENU_DETAIL_LINK_ATTACHMENT_DETAILS)
    if request.method == 'GET':
        language_code = attachment_details.language_version.language_code
        form = AttachmentDetailsForm(
                available_languages,
                language_preference=request.user.userprofile.language_preference,
                file_required=False,
                initial=dict(
                    model_to_dict(attachment_details),
                    language_code=language_code
                )
        )
    elif request.method == 'POST':
        form = AttachmentDetailsForm(
            available_languages,
            language_preference,
            False,  # file_required
            request.POST,
            request.FILES
        )
        if form.is_valid():
            cd = form.cleaned_data
            if cd['attachment_document'] is not None:
                print 'removing previously uploaded file'
                attachment_details.attachment_document.delete(save=False)
            attachment_details.fill(cd)
            attachment_details.save()
            messages.success(request, _('successfully updated.'))
            return redirect(settings.MENU_DETAIL_LINK_ATTACHMENT_DETAILS)

EDIT

Here is an example of what I am trying to hide from the user - in place of the link, display the actual uploaded file image. The image below is of the django admin, but I want to hide the link and display the uploaded image in the edit template:

Supress the Currently prompt and uploaded file link

I have a related post here.

Community
  • 1
  • 1
user3354539
  • 1,245
  • 5
  • 21
  • 40

3 Answers3

1

To hide the currently displayed image link you can simply override get_context (below is the example for ClearableFileInput which is similar to FileInput).

It's very useful to check the source code when you're looking for solutions of this kind.

Django is an open source module, so you can look for the source code on GitHub: https://github.com/django/django/blob/main/django/forms/widgets.py

class ClearableFileInputCustom(forms.ClearableFileInput):
    def get_context(self, name, value, attrs):
        context = super().get_context(name, value, attrs)
        context['widget']['is_initial'] = False
        return context
darklord
  • 11
  • 1
0

I used this snippet in an old project. It's not great because you have to refresh the page/save the model, but it does what I think you want.

Widget:

class AdminImageWidget(forms.FileInput):                                    
    """A ImageField Widget for admin that shows a thumbnail."""             

    def __init__(self, attrs={}):   # pylint: disable=E1002,W0102           
        super(AdminImageWidget, self).__init__(attrs)                       

    def render(self, name, value, attrs=None):  # pylint: disable=E1002     
        output = []                                                         
        css = {'style': 'clear:left;float:left;margin:1em 1em 0 0;'}        
        output.append(super(AdminImageWidget, self).render(name, value,     
                                                           attrs=css))      
        if value and hasattr(value, "url"):                                 
            output.append(('<a target="_blank" href="%s">'                  
                           '<img src="%s" alt="" '                          
                           'style="float:left;border:1px solid black;" /></a> '
                           % (value.url, value.url)))                       
        return mark_safe(u''.join(output)) 

To use it in the admin:

class SomeAdminForm(forms.ModelForm):
    class Meta:
        model = MyModel
        widgets = {
            'my_image_field_name': AdminImageWidget(),
        }

class SomeAdmin(admin.ModelAdmin):
    form = SomeAdminForm
Two-Bit Alchemist
  • 17,966
  • 6
  • 47
  • 82
0

You will have to set the src attribute of the img tag in your template in order to display the image successfully.

<img src="{{attachment_details.file_url}}"/>

{{attachment_details.file_url}} of course has to be replaced with however you are retrieving your file url.

inejc
  • 550
  • 3
  • 14
  • nejc92, the file image link is created dynamically from the python code, so I cannot just drop the suggested template code into the template, as this will just add the image but not replace the actual link.I am thinking that the link must be replaced in the python views.py file code. – user3354539 Feb 22 '15 at 21:04
  • please take a look at the official django docs about templates. when you use a variable in the template like this: {{ variable_name}}, it will get replaced with the actual value from the python code. – inejc Feb 23 '15 at 00:25
  • nejc92, I already have `` which does display the image but does not hide the link.**How do I hide the link** as shown in the post qiestion above? – user3354539 Feb 23 '15 at 01:10
  • your question is unclear to me then. you have successfully displayed the image, but the link is still there and you want to remove it? simply delete the a tag from the template and the link should be gone – inejc Feb 23 '15 at 08:54
  • nejc92 - I solved this using one of your comments above. You didn't provide me the actual solution, but you did point me in the right direction, so I give you the bounty. Thanks, – user3354539 Feb 24 '15 at 01:09