1

I have a Django blog application wherein while posting a blog, a file can be attached and submit as well.

Here is the views.py code:

   def user_own_blog(request):
       if request.method == 'POST' and request.FILES['blog_document']:
            title_b = request.POST.get('blog_title')
            content_b = request.POST.get('blog_content')

            file1 = request.FILES['blog_document']
            fs = FileSystemStorage()
            document_name = fs.save(file1.name, file1)
            uploaded_document_url = fs.url(document_name)

            b = Blog(title=title_b, content=content_b, blog_document=uploaded_document_url)

            b.save()

            return render(request, 'mysite/portfolio.html')
      else:
            return render(request, 'mysite/blog.html')

And here is the MEDIA_ROOT and MEDIA_URL path names:

     STATIC_URL = '/static/'
     MEDIA_URL = '/media/'
     MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

And following is the code for urls.py inside mysite app:

        urlpatterns=[ .....
        ......
        ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

This is the project structure, wherein I need the media folder to be present directly under the Assignment1 project

enter image description here

While the file is getting uploaded successfully, it shows up as follows in the /api.

But there are two media paths being created: /media/media as shown below: I am not able to find the duplicate fields that I might have created.

enter image description here

And on clicking the file link: the 404 not found error occurs. I think the MEDIA_ROOT file name is not correct.

HTML code for blog.html:

     {% extends 'mysite/base.html' %}
       {% load static %}

     {% block content %}

<div class="container">
    <div class="row">
        <div class="col-sm-6 mx-auto" style="margin-top: 70px">
              <form action="{% url 'user_own_blog' %}" method="POST" enctype="multipart/form-data">
                         {% csrf_token %}
                   <div class="form-group row">
                     <label for="example-email-input" class="col-2 col-form-label">Title</label>
                    <div class="col-10">
                        <input name = "blog_title" class="form-control" type="text">
                    </div>
                </div>

                <div class="form-group row">
                    <label for="example-email-input" class="col-2 col-form-label">Content</label>
                    <div class="col-10">
                        <textarea name = "blog_content" class="form-control" rows = "5" cols = "50" type="text"> </textarea>
                    </div>
                </div>

                <div class="form-group row">
                    <label for="example-email-input" class="col-2 col-form-label">Upload File</label>
                    <div class="col-10">
                        <input name = "blog_document" class="form-control" type="file">
                    </div>
                </div>

                <div class="pull-right">
                    <button type="submit" class="btn btn-primary float-right">Post</button>
                </div>
            </form>
        </div>
    </div>

</div>

{% endblock %}
halfer
  • 19,824
  • 17
  • 99
  • 186
Simran
  • 593
  • 1
  • 14
  • 37
  • Is your media files present inside your app's media folder? – Bidhan Majhi Dec 05 '18 at 07:21
  • no it's inside the main project i.e assignment1, not inside 'mysite' – Simran Dec 05 '18 at 07:29
  • This is because your media root set to be in project file. For development stage that is perfect. As you want it inside your app folder refer it as `appname/media` in media root. But media files and static files inside an app is not usually recommended. – Bidhan Majhi Dec 05 '18 at 07:41
  • no the media file lies directly inside the project not appname/media – Simran Dec 05 '18 at 08:27

2 Answers2

5

If you want to locate the uploaded file location in the root:

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

else:

MEDIA_URL = '/media/'
MEDIA_ROOT = 'C:/Users/xyz/Assignment1/mysite/media/' #if windows pay attention to the slashes

Also follow this pattern for your url:

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

EDIT: I think that the issue is not with the media folder it is how you save and retrieve the document. Below I will put the required parts for proper upload and retrieve.

models.py

blog_document= models.FileField()

views.py

def user_own_blog(request):

   if request.method == 'POST' and request.FILES:
       form = BlogForm(request.POST,
                       request.FILES)
       blog = Blog()
       if form.is_valid():
           blog.title_b = form.cleaned_Data['title']
           blog.content_b = form.cleaned_Data['content']
           blog.file = form.cleaned_Data['blog_document']
           blog.save()

        return HttpRequestRedirect(reverse('portfolio'))
    else:

        form = BlogForm()
    return render(request, 
                  'mysite/blog.html',
                  {'form': form})

To retrieve the upload file url there is default method .url. You just pass the query to the template (Modelname.objects.filter(title__iexact='something'))

{{ query.file.url}}

Note: You need to create a form in forms.py(if you don't have to create one). And values are retrieved from the form with the cleaned_data method. Research on this.

Rarblack
  • 4,559
  • 4
  • 22
  • 33
  • nope, this method is not working, on clicking the file url link from the api list, the same 404 not found error persists – Simran Dec 05 '18 at 07:13
  • have you created media folder by yourself? – Rarblack Dec 05 '18 at 07:27
  • no, after creating MEDIA_URL and MEDIA_ROOT variables in settings.py, and after runserver, the media folder was automatically created inside the main project – Simran Dec 05 '18 at 07:33
  • can you post your html? you are retrieving document in a wrong manner – Rarblack Dec 05 '18 at 08:28
1

if you have already added this in your settings.py file

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

and still you are getting 404 error then it might be because you have to add media_url in main urls.py aswell

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

this is how you can add it. If you want to read more in details then read this article

Zohab Ali
  • 8,426
  • 4
  • 55
  • 63