Upload and rename two different files in two different folders using django? - python

I could upload two different files in the same folder using django. But I have to upload it to two different folders and also rename the files I uploaded as target.{file_extension} and probe.{file_extension}.I have no idea as I am a beginner to django.Could anyone please help me with my issue.
My codes are:
In django model.py
dirname = datetime.now().strftime('%Y.%m.%d.%H.%M.%S')
class Document(models.Model):
docfile = models.FileField(upload_to=dirname)
In views.py
def test(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile=request.FILES['docfile'])
newdoc.save()
else:
form = DocumentForm() # An empty, unbound form
documents = Document.objects.all()
return render(
request,
'personal/basic.html',
{'documents': documents, 'form': form}
)
And in my basic.html
<form action="/simulation/" method="post" enctype="multipart/form-data" single>
{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
<input type="submit" value="Upload" name = "file1"/></p>
</form>

if you check django docs for FileField you see upload_to supports custom method:
(from django docs)
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.user.id, filename)
class MyModel(models.Model):
upload = models.FileField(upload_to=user_directory_path)
as you can see in your custom method you have access to current instance which can be used for generating your custom path to save file.

Related

Upload any file in django

I was trying to create a function for upload file in Django. First time I running my code, it's cannot upload a file. So, I was trying to improve my code and what I got its error. I thought the error it's weird because I always used that and I never get an error. I'll show my code.
models.py
class UploadFiles(models.Model):
File = models.ImageField(upload_to = 'Images/', default='Images/')
views.py
def upload_file(request):
if request.method == 'POST':
form = UploadFile(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('home')
else:
form = UploadFile()
return render(request, 'girl/upload.html', {'form': form})
forms.py
class UploadFile(forms.Form):
title = forms.CharField(max_length=50)
file = forms.FileField
upload.html
{% extends 'girl/base.html' %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
<p>Return to home</p>
{% endblock %}
error:
django.urls.exceptions.NoReverseMatch: Reverse for '/' not found. '/' is not a valid view function or pattern name.
urls.py
url(r'^cat/upload/$', views.upload_file, name='uploads')
Any help would be appreciated.
This is the line the error is
<p>Return to home</p>
Change it to
<p>Return to home</p>
And in your forms to
class UploadFile(forms.ModelForm)
class Meta:
model=UploadFiles
fields ='__all__'

How correctly save multiple files in django?

I need form where user can create article with several images. I use django-multiupload app for image field. I can select several images but when I try to submit the form I have message under the image field: "Field is empty and field is required". Where is my mistake? Why I have such message when image field is not empty?
Also maybe someone can advice good examples or apps to save several images. I would be very grateful for any help.
models.py:
class Article(models.Model):
description = models.TextField(_('Description'))
class Image(models.Model):
article= models.ForeignKey(Article, on_delete=models.CASCADE)
image = models.FileField(_('Image'), upload_to='images/%Y/%m/%d/')
forms.py:
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ('description', )
image = MultiFileField()
def save(self, commit=True):
instance = super(ArticleForm, self).save(commit)
for each in self.cleaned_data['image']:
Image.objects.create(image=each, article=instance)
return instance
views.py:
def article_add(request):
data = dict()
if request.method == 'POST':
article_form = ArticleForm(request.POST, request.FILES)
if article_form.is_valid():
article = article_form.save(commit=False)
******
article.save()
data['form_is_valid'] = True
articles = Article.objects.all
context = {'articles': articles}
context.update(csrf(request))
data['html_article'] = render_to_string('project/article_list.html', context)
else:
data['form_is_valid'] = False
else:
article_form = ArticleForm()
context = {'article_form': article_form}
data['html_article_form'] = render_to_string('project/article_add.html', context, request=request)
return JsonResponse(data)
article_add.html:
{% load widget_tweaks %}
<form method="post" action="{% url 'article_add' %}" class="article-add-form">
{% csrf_token %}
{% for field in article_form %}
<div class="form-group{% if field.errors %} has-danger{% endif %}">
<label class="form-control-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
{% render_field field class="form-control" %}
{% for error in field.errors %}
<div class="form-control-feedback">{{ error }}</div>
{% endfor %}
</div>
{% endfor %}
<button type="submit">Submit</button>
</form>
Try adding "min_num" constraint on the image field,
image = MultiMediaField(min_num=1, media_type='image')
EDIT
def article_add(request):
if request.method == 'POST':
article_form = ArticleForm(request.POST, request.FILES)
if article_form.is_valid():
article = article_form.save(commit=False)
******
article.save()
#assume you have already a view in the name 'article_list'.
return redirect('article_list')
else:
article_form = ArticleForm()
context = dict(article_form=article_form)
return render(request, 'project/article_add.html', context)
The problem maybe because you were trying to render two templates in a single view, also when using django template rendering render is a shortcut function, which is mostly preferred to use, rather than string converting and parsing into json.
Also, 'article_list' must be another view, which shows the list of all the articles, after adding a new article, you should consider redirecting to the list view. Here you were trying to render multiple templates, in a single view. You could make of something like this in your list view,
def article_list(request):
articles = Article.objects.all()
context = dict(articles=articles)
return render(request, 'project/article_list.html', context)
Although, these are my personal opinion regarding the code you just shared. Try this approach...

django inline formset to upload multiple files not rendering form

I have model:
class MediaInfo(models.Model):
title = models.CharField(max_length=50,blank=True)
description = models.CharField(max_length=255,blank=True)
media_file = models.FileField(upload_to=get_upload_file_name)
def __unicode__(self):
return self.title
class Media(models.Model):
media_files = models.ForeignKey(MediaInfo)
def __unicode__(self):
return self.media_files
What I want is to render a template where I get a simple browse button and I can select and upload multiple 'media_file'.
I came to know that it can be performed from inline formset so used it in my view. My view looks like
def MediaAddView(request):
#med = MediaInfo.objects.al()
MediaInlineFormset = inlineformset_factory(MediaInfo, Media)
if request.method == "POST":
formset = MediaInlineFormset(request.POST, request.FILES)
if formset.is_valid():
formset.save()
return HttpResponseRedirect("some url")
else:
return render_to_response("media_add.html",
{"formset":formset,},
context_instance=RequestContext(request))
else:
formset = MediaInlineFormset()
return render_to_response("media_add.html",
{"formset":formset,}, context_instance=RequestContext(request))
and my template is :
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{form.media_file}}
{% endfor %}
<input type="submit" value="Submit" />
</form>
When I do this instead of getting a browse button to upload file I am getting only submit button.
How can I get just a browse button and add multiple files or images ?
Whats wrong in my code ?
Need help

Multiple file uploads using formset?

models.py
class Album(models.Model):
file_upload = models.FileField(upload_to=content_file_name)
name_content = models.CharField(max_length=100)
And Function is here
def content_file_name(instance, filename):
upload_dir = os.path.join('uploads', 'resource')
return os.path.join(upload_dir, filename)
forms.py
class Albumform(forms.Form):
name_content = forms.CharField(max_length=100)
file_upload = forms.FileField( 'please select' )
This is my views.py
from django.forms.formsets import formset_factory
def viewalbum(request):
AlbumFormSet = formset_factory(Albumform, extra=3, max_num=10,)
if request.method == 'POST':
formset = AlbumFormSet(request.POST, request.FILES)
if formset.is_valid():
albumvalue = Album()
albumvalue.name_content = request.POST.get('name_content', None)
albumvalue.file_upload = request.FILES['file_upload']
albumvalue.save()
return HttpResponseRedirect(reverse('views.viewalbum'))
else:
formset = AlbumFormSet()
return render_to_response('audio/test.html',{'formset': formset}, context_instance=RequestContext(request))
and the html looks like this
<form action="" method="POST" enctype="multipart/form-data">
{{ formset.management_form }}
{% csrf_token %}
<table>
{% for form in formset.forms %}
{{ form }}
{% endfor %}
</table>
The problem is i can only upload one file at the time. Give me solution to upload multiple file in the same time and saved into resource folder. Thanks
If you want to upload multiple files, then you need multiple filefields. That is your option A. If you choose to go for it, create formset and use it to provide multiple file upload.
your option B is to use some kind of javascript widgets that make multiple file uploads possible.

Management form error while using modelformsets ('ManagementForm data is missing or has been tampered with')

I have a models.py class as below
class Educational_Qualification(models.Model):
user = models.ForeignKey(User)
exam = models.CharField(max_length=40)
pass_month = models.CharField(max_length=40)
I have a views.py as below
def create_qualification(request):
QFormSet = modelformset_factory(Educational_Qualification, extra=3, exclude=("user",))
if request.method == "POST":
formset = QFormSet(request.POST, request.FILES)
if formset.is_valid():
formset.save()
for form in formset.forms:
if form.is_valid():
quali= form.save(commit=False)
quali.user = request.user
quali.save()
return HttpResponse("Saved")
else:
return HttpResponse("Snafu")
else:
formset = QFormSet()
return render_to_response("register/edu.html", {"formset":formset}, context_instance=RequestContext(request))
When I submit the form, it throws up the validation Error. stating that ManagementForm data is missing or has been tampered with'
I have formset.management_form in my template.
What could be the issue?
The error is not in your views or the models, but in the templates.
The right way to render the formset, is:
<form method="post" action="">
<table>
{{ formset }}
</table>
</form>
or
<form method="post" action="">
{{ formset.management_form }}
<table>
{% for form in formset.forms %}
{{ form }}
{% endfor %}
</table>
</form>
I guess, you are looping over the forms in the templates without including the management form?
It also happens if there are multiple views involved and one of them is not aware of the formset prefix.
Get view:
def someview(request):
...
formset = Formset(prefix="foo")
...
Post view (Potentially an Ajax form submit handler):
def ajaxview(request):
...
formset = Formset(request.POST, prefix="foo") # here
...

Categories

Resources