I am trying to upload a file in django.
It allows me to add the file in the form and submits with no errors but nothing gets stored. I am using django-crispy-forms
models.py
class Upload(models.Model):
upload = models.FileField(upload_to='.')
views.py
class UploadsView(UpdateView):
form_class = UploadForm
template_name = 'upload.html'
model = Upload
forms.py
class UploadForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UploadForm, self).__init__(*args, **kwargs)
class Meta:
model = Upload
fields = ('upload',)
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, '..', 'media')
MEDIA_URL = '/media/'
form.html
<form method="POST" action="">{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-primary" type="submit" value="Submit" />
<button type="button" class="btn btn-danger">Cancel</button>
</form>
You need to change your form tag:
<form method="POST" action="" enctype="multipart/form-data">
From the documentation:
Note that request.FILES will only contain data if the request method was POST and the <form> that posted the request has the attribute enctype="multipart/form-data". Otherwise, request.FILES will be empty.
Related
Guys I'm new to django I tried uploading images in the imagefield but it's not creating media folder and the database image column is also blank.
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
models.py
class Profile(models.Model):
name = models.CharField(max_length=50)
image = models.ImageField(upload_to='images/')
image.html
<form method="POST" enctype="multipart/form-data>
{% csrf_token %}
<input type="file" class="form-control" id="customFile" name="image"/></div>
<input type="text" class="form-control" name="name" placeholder="">
</div>
</form>
views.py
def hotel:
if request.method == "POST" :
post=Profile()
post.image= request.POST.get('image')
post.name = request.POST.get('name')
post.save()
return redirect('/vendor_dashboard/profile_pic')
return render(request,'profile.html')
Even tried manually creating the media file Django.
Still nothing!!
Any help Will be appreciated
Uploaded files are in request.FILES instead of request.POST. So your file handling should look like this:
# post.image= request.POST.get('image')
post.image = request.FILES['image']
I'd recommend to read the Django docs about file uploads
use request.FILES:
def hotel:
if request.method == "POST" :
post=Profile()
post.image= request.FILES['image']
post.name = request.POST.get('name')
post.save()
return redirect('/vendor_dashboard/profile_pic')
return render(request,'profile.html')
You have to include {{form.media}} to the django form template if you want to post any type of media to django
<form method="POST" enctype="multipart/form-
data>
{% csrf_token %}
{{form.media}}
<input type="file" class="form-control"
idd="customFile" name="image"/></div>
<input type="text" class="form-control"
name="name" placeholder="">
</div>
</form>
edit:
and in views.py you have to use request.FILES to get any media file(forgot to mention this)
request.FILES.get('image')
and to get the image from media use .url
{% Profileobject.image.url %}
I have created a blog website and I want to display images for every post like YouTube thumbnails. I created an image field in my Post Class but it is not saving my image in the media folder when I create a post.
Post class in models.py:
class Post(models.Model):
name = models.CharField(default='Concert', max_length=100)
invite = models.ImageField(default='invite.jpg', upload_to='invite_pics')
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
This is my CreatePost class in views.py:
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
template_name = 'home_page/post_form.html'
fields = ['name', 'invite']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
I have set the MEDIA_ROOT and MEDIA_URL in settings.py:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
post_form.html:
<div class="container">
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Create New Event</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Post</button>
</div>
</form>
</div>
</div>
So as I have said earlier, the image is not getting saved to media/invite_pics what should I do?
In order to submit data and files, you need to specify the enctype="…" parameter of the form:
<form enctype="multipart/form-data" method="POST">
…
</form>
I am making a Django website where I need to display images selected by user.
These are the things I've done:
Html form for image:
<form action="" method="POST">
{% csrf_token %}
<div class="form-group">
<label >Article Logo</label>
<input type="file" class="btn btn-primary" name="article_image">
</div>
<input type="submit" class="btn btn-success">
</form>
models.py
class Content(models.Model):
article_image = models.ImageField(upload_to = 'media', null=True)
views.py
def submit_article(request):
if request.method == 'POST':
a_image = request.FILES['article_image']
new_article.article_image = a_image
new_article.save()
I've added below code to settings.py to specify media directory:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
Added below code to urls.py of the website:
urlpatterns = [
path(r'admin/', admin.site.urls),
url(r'', include('logio.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The form is not able to add images to the media folder. If I'm adding images through the admin panel it works.
Thanks in advance....
You need to add enctype="multipart/form-data" to your form, like this:
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
For more information, please check the documentation.
Just a suggestion, it is better to use a Django form to handle this. For example, you can have a form:
class ContentForm(forms.ModelForm):
class Meta:
model = Content
fields = ['article_image']
Then pass this form via context to template and render it:
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="submit'>
</form>
Finally, handle validation in view:
def submit_article(request):
if request.method == 'POST':
form = ContentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
...
When I use the form provided by django admin everything works fine. But after creating my own form, django does not write data to my model. Is something missing in my code?
Models.py
class Offert(models.Model):
name = models.CharField(max_length=50)
file = models.FileField(upload_to='app/documents/')
forms.py
class OffertFormCV(forms.ModelForm):
class Meta:
model = Offert
fields = ( 'name',
'file')
views.py
def my_views(request):
if request.method == 'POST':
form = OffertFormCV(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('app:thank_you_page'))
else:
form = OffertFormCV()
context = {'form': form}
return render(request, 'form_application.html', context)
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls', namespace='app'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'app/media')
form_application.html
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Send</button>
</form>
After sending the form, nothing happens. Any help will be appreciated.
You need to add enctype="multipart/form-data" to your form to be able to upload files:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Send</button>
</form>
I have this HTML template
<html><body>
<form method="POST">
{% render_form submitSerializer %}
<input type="submit" value="Save">
</form>
</body></html>
this serializer
class SubmitSerializer(serializers.ModelSerializer):
submittedFile = serializers.FileField()
class Meta:
model = Submit
fields = {'submittedFile', 'result'}
read_only_fields = {'result'}
and this view
class SubmitView(APIView):
renderer_classes = [renderers.TemplateHTMLRenderer]
def get(self, request, *args, **kwargs):
return Response({'submitSerializer':submitSerializer}, template_name='singlelesson.html')
def post(self, request, *args, **kwargs):
submit = Submit(lesson=lessonInstance, user=self.request.user, submittedFile = self.request.data['submittedFile'])
serializer = SubmitSerializer(submit)
#compare_files returns true if two files contain same text
result = compare_files(correct_solution, self.request.POST.get('submittedFile'))
serializer.save(result = result)
return Response({'submitSerializer':serializer}, template_name='singlelesson.html')
Problem is that the form uploads not the file but its name and I get type error when comparing the two files. How do I make the form upload the file instead?
You should extract the file from the FILES QueryDict in the request object, not POST. e.g.:
self.request.FILES['submittedFile']
Or the django-rest-framework way:
request.data['submittedFile']
For more explanation check out:
http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser
EDIT: Also change form to:
<html><body>
<form method="POST" enctype="multipart/form-data">
{% render_form submitSerializer %}
<input type="submit" value="Save">
</form>
</body></html>
And SubmitView to:
class SubmitView(APIView):
parser_classes = (MultiPartParser,)
...