I have been googling this for an ours and can't find the solution. When I use admin panel, image is loading to the directory that is needed. But when I create post from the frontend, the image is just loading to the main directory, which is media. I now that I it will work if I use django forms and createview, but I need adding a post with a function like I did. I think this problem might happen, because ImageField needs validating. But I don't know how to validate it outside the django forms context.
I have model Posts with ImageField image and upload_to option:
class Posts(models.Model):
image = models.ImageField(upload_to="posts/%Y/%m/%d", null=True,blank=True)
then in views.py the function, that adds new post:
@login_required
def add_post(request):
if request.method == 'POST':
title = request.POST.get('title')
content = request.POST.get('content')
upload_file = request.FILES['image']
fs = FileSystemStorage()
image = fs.save(upload_file.name, upload_file)
post = Posts(title=title, content=content, image= image)
post.author = request.user
post.save()
from django.http import HttpResponseRedirect
#return redirect(post.get_absolute_url())
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
return render(request ,'users/user-detail2.html')
and the which displays the form:
<form action="{% url 'add_post' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title">Share Your Mood</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body custom-scroll">
<input type="text" name="title" placeholder="Post title" class="form-control">
</div>
<div class="modal-body custom-scroll">
<input type="file" id="image" name="image" rows="5" class="form-control">
</div>
<div class="modal-body custom-scroll">
<textarea name="content" class="share-field-big custom-scroll" placeholder="Say Something"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="post-share-btn" data-dismiss="modal">cancel</button>
<input type="submit" value="Post" class="post-share-btn">
</div>
</form>
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
main urls.py
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
You don't need to use FileSystemStorage
class here. Just save the file as below
from django.http import HttpResponseRedirect
@login_required
def add_post(request):
if request.method == 'POST':
title = request.POST.get('title')
content = request.POST.get('content')
upload_file = request.FILES['image']
post = Posts(title=title, content=content, image=upload_file, author=request.user)
post.save()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
return render(request, 'users/user-detail2.html')