In my Django "sources" project I have the "bulletins" app.
I have a view "model_form_upload" inside of which I get the uploaded file name ("csvFilename") when I upload it.
views.py
from bulletins.forms import ErnageForm
from bulletins.models import ErnageModel
from bulletins.pretreatment import pretreatment
def model_form_upload(request):
if request.method == 'POST':
form = ErnageForm(request.POST, request.FILES)
if form.is_valid():
form.save()
for filename, file in request.FILES.items():
csvFilename = file.name
resultPretreatment = pretreatment()
print(resultPretreatment)
return redirect('proceed_FT')
else:
return redirect('upload_fail')
else:
form = ErnageForm()
return render(request, 'bulletins/upload_csv.html', {'form': form})
Beside that, I have a python script "pretreatment.py" that effectuates a bunch of pandas-dataframe transformations on my csv file.
pretreatment.py
def pretreatment(csvFileToTreat="..."
#... all the transformations with pandas dataframes...
df.to_csv(txtExportFilePath, index=False, header=None, sep='\t')
models.py
class ErnageModel(models.Model):
csv = models.FileField(upload_to="METEO ERNAGE/{0}/{1}".format(yearToTreat,monthToTreat))
My csvFilename will always be a string of this type : "Ernageyyyymm.csv".
My question here is : How can I collect my csvFilename variable out of the views.model_form_upload function to use its date information it in the pretreatment python script variables "csvFileToTreat" and "txtExportFilePath".
Those two ones are of the type "path/Ernage{0}{1}.format(yearToTreat,monthToTreat).
As I have to use it each month I would like to have my files uploaded in media/METEO ERNAGE/{0}/{1}".format(yearNumber,monthNumber) as you can see in the FileField upload_to and then everything happening in this directory. So the pretreatment charges the uploaded file and then export in it also.
I hope all this is as clear as possible, thank you for your help.
store csvFilename name in a session like this:
request.session['file']=csvFilename
and you can use this session where ever you want like this.
csvFilename =request.session['file']
Related
I am currently using Django's forms to create a FileField that allows the user to upload a file. However, after I select the file, it creates an object of type django.core.files.uploadedfile.InMemoryUploadedFile, which is a copy of the original file.
How would I go about to get the original path of this file so I can either modify or replace it?
# forms.py
class UploadFile(forms.Form):
file = forms.FileField(label="Select File: ", required=True)
# views.py
def get_path(response):
context = {}
if response.method == "POST":
form = UploadFile(response.FILES)
if form.is_valid():
file = form.cleaned_data["file"]
# Is there a way to get the original file path or should I just not use FileField?
print("The File Path Here")
temporary_file_path function
if form.is_valid():
file = form.cleaned_data["file"]
print(file.temporary_file_path())
Not sure why you'd want to try modifying an InMemoryUploadedFile file path. However, just keep in mind the term "InMemory".
The file has not been saved as yet, so there will be no path associated with the file before saving. To my knowledge (I stand corrected if I'm wrong here), InMemoryUploadedFile do not have a path attribute either, but content/file, a filename, etc.; in which the filename can be modified. You can see the doc here.
You could make modifications to the filename though if you wish by doing the following:
if form.is_valid():
form.cleaned_data["file"].name = "modify.txt" # or to whatever filename and extension you want.
form.save() # If you have a save method defined
However, you could get a little creative in saving the file to a specific path within the media folder though. For example:
# forms.py
import os
from django.conf import settings
class UploadFile(forms.Form):
file = forms.FileField(label="Select File: ", required=True)
# The save method that will save the file to a specific location in the media folder.
def save(self):
filename = file.name
folder = 'uploaded/'
# Create the folder if it doesn't exist.
try:
os.mkdir(os.path.join(settings.MEDIA_ROOT, folder))
except:
pass
# Save the uploaded file inside that folder.
file_path = os.path.join(settings.MEDIA_ROOT, folder, filename)
with open(file_path, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
# view.py
def get_path(response):
if response.method == "POST":
form = UploadFile(response.FILES)
if form.is_valid():
file = form.cleaned_data["file"]
# file.name = "modify.txt" # Can modify here if necessary...
form.save()
I am learning django. I am stuck with this problem.
I have created a form in which a user uploads a text file and selects a gender. The user is also supposed to write the name of the text file in the text box.
sample output
In the backend I want to save the name of the text file along with the gender in a model. The purpose of doing this is because when multiple users will use the application, I should know which user selected what gender so that I can produce the desired output.
As I have already mentioned the user needs to type the name of the file, I was thinking is it possible to get the name of the file from the uploaded file and then save it to the model so the user need not type the name of the file and hence no text box.
Here is the link to my git repository - https://github.com/AnshulGupta22/auto_generation.git
Can someone please tell me how to do it? As I already said I am new to django and some help will be appreciated.
You can get the name of file from request.POST and you can create an object for file_name so:
##in views.py
def get_gender(request):
if request.method == 'POST':
form = GenderForm(request.POST)
uploaded_file = request.FILES['document']
file_name = request.FILES["name"] #NEW
Gender.objects.create(file_name=file_name) #NEW
fs = FileSystemStorage()
name = fs.save(uploaded_file.name, uploaded_file)
fbh = name[:-4]
if form.is_valid():
form.save()
run(["gnome-terminal", "--", "sh", "-c", f"espeak -ven+m1 -f {uploaded_file.name} -w {fbh}.wav "])
return HttpResponse("Blog created")
##in models.py
class Gender(models.Model):
file_name = models.CharField(max_length=120) #NEW
I am creating an app that allows users to convert their .ifc (3D model) files into other data forms (.xlsx, filtered .xlsx, json). I have managed to implement the upload part, but now I am not sure about the download.
I would like to create a "download" button that takes in the users desired download path (maybe even file name). When I have the path I can start my conversion function with the last uploaded file.
def model_form_download(request):
if request.method == 'POST':
download_path = ??? #How to take in the user defined upload path?
last_model = Document.objects.latest("uploaded_at")
last_model_name = last_model.document.name
MODEL_DIR = Path(MEDIA_DIR) / last_model_name
model = parser(MODEL_DIR)
xlsx_name = Path(last_model_name).stem
XLS_DIR = Path(download_path) / (xlsx_name + '.xlsx')
model[1].to_excel(XLS_DIR)
return render(request, 'core/model_form_download.html')
return render(request, 'core/model_form_download.html')
The extra question here is how to take in the user choice of prefered conversion format and use in this view function?
def model_form_download(request):
if request.method == 'POST':
download_path = ??? #How to take in the user defined upload path?
last_model = Document.objects.latest("uploaded_at")
last_model_name = last_model.document.name
MODEL_DIR = Path(MEDIA_DIR) / last_model_name
model = parser(MODEL_DIR)
xlsx_name = Path(last_model_name).stem
XLS_DIR = Path(download_path) / (xlsx_name + '.xlsx')
model[1].to_excel(XLS_DIR)
return render(request, 'core/model_form_download.html')
return render(request, 'core/model_form_download.html')
How to take in the user defined upload path?
if you have a form on the frontend like this:
<form>
<input name="download_path" .../>
...
Then in you django view you can access it from request
download_path = request.POST.get("download_path")
the same goes for the conversion format, just add it to a form and access it from the request object.
although really you should consider using forms: https://docs.djangoproject.com/en/3.2/topics/forms/
I am trying to load the csv files I upload to my sqlite3 db. I am able to upload the csv into a folder but it doesn't appear on my db. The db table structure contains as many columns as the csv with the corresponding data types; but the column names in the db table structure are different as in the csv, as some of the columns names in the csv contain spaces and special characters (like accents for example).
My goal is to allow the user to upload a csv file that will be loaded to the db. I was also wondering if its possible to increment the db each time a new csv is loaded (for example: I upload a file now which is loaded to the db then the second time I add, the newer details are added to the db without deleting the previous ones). Apologies if I am unclear and asking too many things at once.
Here is my model, form, function (handle upload) & views .py files:
# models.py
class UploadForm(models.Model):
file = models.FileField()
class Meta:
db_table = "db_table"
# forms.py
class UploadForm(forms.ModelForm):
class Meta:
model = UploadForm
fields = "__all__"
# functions.py
def handle_uploaded_file(f):
with open('vps_app/static/upload/'+f.name, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
# views.py
def index(request):
if request.method == 'POST':
Uploaded = UploadForm(request.POST, request.FILES)
if Uploaded.is_valid():
handle_uploaded_file(request.FILES['file'])
return HttpResponse("File uploaded successfuly")
else:
Uploaded = UploadForm()
return render(request, "index.html", {'form': Uploaded})
Thanks in advance.
You can't do this automatically, you need to handle it yourself, here is a sample for handle_uploaded_file
def handle_uploaded_file(f):
for row in csv.DictReader(f):
m = Model.objects.create(**row)
I'm using Django to host a web application, and I would like to obtain a CSV file from the user, and process this information (using Python). I am currently using this line of code in the HTML to obtain the CSV file:
<input type="file" accept="text/csv" id="mycsv">
Where in the Django project should I obtain the information from the CSV file, and how would I go about doing this? (I know the question is broad and doesn't give context for my specific project, but I figure that once I know how to access the data in the CSV I can figure the rest out).
Step 1: upload the file
# forms.py
from django import forms
class UploadFileForm(forms.Form):
file = forms.FileField()
Step 2: parse data and update database
# views.py
import csv
from .models import YourModel
def myview(request):
if request.method == "POST":
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
reader = csv.reader(form.cleaned_data['file'])
for row in reader:
try:
some_instance = YourModel.objects.get_or_create(row[...])
...
Files uploaded by the user will go to the media folder that you have defined in your settings.py file.
You should be able to access user uploaded files in the media directory from your python code with something like this:
file_ = open(os.path.join(settings.MEDIA_ROOT, 'name_of_file'))
More info on MEDIA_ROOT and MEDIA_URL can be found here.