How to upload a file from django view using filepath - django

I have to upload a file from django views using the file path from the local system. I'm using models.create method to save the filepath. But the image is not getting uploaded into the media directory.
I have tried the Content and File from django core.utils but it deos not work
def createevent(request):
file_path = os.path.join(settings.FILES_DIR) # Getting the directory with files
f = []
for (dirpath, dirnames, filenames) in walk(file_path):
f.extend(filenames)
break
f.remove(".DS_Store")
img = random.choice(f) # Select a random file
pa = os.path.abspath(img) # absolute file path
# pa = (img,File(pa))
response = File(pa)
print(pa)
loc = "School Ground"
if request.method == 'POST':
get_dateof = request.POST.get('dateof')
get_nameof = request.POST.get('nameof')
get_descof = request.POST.get('descof')
new_report = Event.objects.create(
name=get_nameof,
description=get_descof,
location=loc,
timeoftheevent=get_dateof,
user=request.user,
image= pa
) #creating a db record
return HttpResponse('')
my models.py
class Event(models.Model):
name = models.CharField(max_length=100,blank=False)
description = models.CharField(max_length=100,blank=False)
location = models.CharField(max_length=100,blank=False)
timeoftheevent = models.CharField(max_length=100,blank=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
image = models.FileField(blank=False)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username

You can try this.
#This would return a path for your saved images using path name/filename you can always tweak this
def user_directory_path(instance,filename):
return '{0}/{1}'.format(instance.name, filename)
class Event(models.Model):
name = models.CharField(max_length=100,blank=False)
description = models.CharField(max_length=100,blank=False)
location = models.CharField(max_length=100,blank=False)
timeoftheevent = models.CharField(max_length=100,blank=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
image = models.FileField(upload_to = user_directory_path, blank=False)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username
then in your views.py and I'm assuming myfile is the name of the file field in your html form
if request.method == 'POST' and and request.FILES['myfile']:
get_dateof = request.POST.get('dateof')
get_nameof = request.POST.get('nameof')
get_descof = request.POST.get('descof')
myfile = request.FILES['myfile']
#creating a db record............
return HttpResponse('')
you can have a look at this article if it helps

Related

how to save django data in to tow model

hi please help me i have to model i want after create and save store the result save to main store
like this
store.name == mainstore.name
store.the_rest_of_quantity==mainstore.quantity
i trying to use signals but i fail
class Store(models.Model):
CHOICES = (
('NUM','number'),
('M','meter'),
)
name = models.CharField(max_length=60)
quantity = models.PositiveSmallIntegerField (validators=[MinValueValidator(0)],default=0,blank=True,null=True)
date_of_add = models.DateTimeField(auto_now_add=True)
add_new_item = models.PositiveSmallIntegerField (validators=[MinValueValidator(0)],default=0,blank=True,null=True)
date_of_remove = models.DateTimeField(auto_now =True)
remove_old_item = models.PositiveSmallIntegerField (validators=[MinValueValidator(0)],default=0,blank=True,null=True)
the_rest_of_quantity = models.PositiveSmallIntegerField (validators=[MinValueValidator(0)],default=0,blank=True,null=True)
accept_stor = models.BooleanField(default = False)
classyfiyed = models.CharField(max_length=3,choices=CHOICES,blank=True,null=True)
def __str__(self):
return 'Device Name :( {0} ) Have Quantity({1}) '.format(self.name,self.quantity)
def save(self, *args, **kwargs):
try:
totla_sum = sum([self.quantity , self.add_new_item])
self.the_rest_of_quantity = int(totla_sum - self.remove_old_item)
except Expression as identifier:
'you add remove bigger than quantity'
return super().save(*args, **kwargs)
class MainStore(models.Model):
name = models.CharField(max_length=120)
quantity = models.PositiveIntegerField (null=True,default=0)
store = models.OneToOneField(Army,on_delete=models.CASCADE,related_name='Store',null=True)
i use signals for solve it
signals.py
#receiver(post_save,sender=Store)
def create_store(sender,instance,created,**kwargs):
if created:
MainStore.objects.get_or_create(Store=instance,name=instance.name,quantity=instance.the_rest_of_quantity)
else:
obj_store = MainStore.objects.filter(Store=instance)
update_store = obj_store.update(name=instance.name,quantity=instance.the_rest_of_quantity)
return update_store
apps.py
from django.apps import AppConfig
class StoreConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'Store'
def ready(self):
import Store.signals
init.py
default_app_config = "Store.apps.StoreConfig"

upload shape file in geodjango

i am Trying to upload a shape file to postgres by django and geopandas. but it return this error:
(psycopg2.errors.DuplicateTable) relation "idx_Village_kcnT1Uu_geom" already exists
this is my model:
class ShapeFile(models.Model):
name = models.CharField(max_length=45)
description = models.TextField()
file = models.FileField(upload_to='user_shape_file')
date = models.DateTimeField(auto_now_add=True)
and i am using this signal to upload it:
#receiver(post_save, sender=ShapeFile)
def post_save_r(instance, **kwargs):
file = instance.file.path
file_format = os.path.basename(file).split('.')[-1]
file_name = os.path.basename(file).split('.')[0]
file_path = os.path.dirname(file)
name = instance.name
connection = 'postgresql://postgres:1234#localhost:5432/geoapp'
with zipfile.ZipFile(file, 'r') as opened_zip:
opened_zip.extractall(file_path)
shape_file = glob.glob(r'{}/**/*.shp'.format(file_path), recursive=True)[0]
gfr = gpd.read_file(shape_file)
epsg = 4326
engine_ = create_engine(connection)
gfr['geom'] = gfr['geometry'].apply(lambda x: WKTElement(x.wkt, srid=epsg))
gfr.to_sql(name, engine_, 'public', if_exists='replace', index=False,
dtype={'geom': Geometry('Geometry', srid=epsg)})
but it return this error:

Field 'xxx' expected a number but got <django.forms.boundfield.BoundField>

Here is my code:
In forms.py
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ("title","business_partner","transaction")
widgets = {
'transaction': forms.NumberInput()
}
In views.py
def uploadpdf(request,pk):
project_form = ProjectForm(request.POST)
if project_form.is_valid() and request.FILES:
project_form.instance.user = request.user
project = Project.objects.get(id=pk)
project.title = project_form['title']
project.business_partner = project_form['business_partner']
project.transaction = project_form['transaction']
project.save()
project = Project.objects.get(id=pk)
file_path = None
for file in request.FILES:
file = request.FILES[file]
pdf_file = PDFFile(file=file, filename=file.name)
pdf_file.project = project
pdf_file.save()
if PRODUCTION:
file_path = HOST_NAME +'/'+ str(pdf_file.file)
else:
file_path = HOST_NAME +'/media/'+ str(pdf_file.file)
resp = HttpResponse(f'{{"message": "Uploaded successfully...", "id": "{project.id}","url":"{file_path}","title": "{project.title}"}}')
resp.status_code = 200
resp.content_type = "application/json"
return resp
else:
return reverse("dashboard:homepage")
When I run this, it says like "TypeError: Field 'transaction' expected a number but got <django.forms.boundfield.BoundField object at 0x000001A803935250>."
Looking forward to hearing a good solution.
You want to use the cleaned_data attribute of the form instead of the field itself like so:
project.transaction = project_form.cleaned_data['transaction']
Edit: Note that you should have to do the same for the other fields.

Django - [Errno 2] No such file or directory error: when attempting to save an uploaded file to a dynamic url

Models.py:
class Enterprise(models.Model):
name = models.CharField(max_length = 100)
def __str__(self):
return f"{self.id}_{self.name}"
class Client(models.Model):
name = models.CharField(max_length = 100)
def __str__(self):
return f"{self.id}_{self.name}"
class Engagement(models.Model):
name = models.CharField(max_length = 100
def __str__(self):
return f"{self.id}_{self.name}"
class StockCount(models.Model):
name = models.CharField(max_length = 100)
def __str__(self):
return f"{self.name}"
class InventoryList(models.Model):
UploadedFile = models.FileField(_('Upload Inventory Listing'), upload_to = file_upload_location, validators=[validate_file_extension], max_length = 500)
enterprise = models.ForeignKey('Enterprise', on_delete=models.CASCADE, related_name = 'inventorylists')
client = models.ForeignKey('Client', on_delete=models.CASCADE, related_name = 'inventorylists')
engagement = models.ForeignKey('Engagement', on_delete=models.CASCADE, related_name = 'inventorylists')
stockcount = models.ForeignKey('StockCount', on_delete=models.CASCADE, related_name = 'inventorylists')
views.py:
def upload(request):
if request.method == 'POST':
form = InventoryListForm(request.POST, request.FILES)
if form.is_valid():
# file is saved
list = form.save(commit = False)
list.enterprise = Enterprise.objects.get(pk = 1)
list.client = Client.objects.get(pk = 1)
list.engagement = Engagement.objects.get(pk = 1)
list.stockcount = StockCount.objects.get(pk = 1)
list.save()
return HttpResponse(f'You have just made a post request - {list.id}')
else:
return render(request, "observe/upload.html", {"form": form})
else:
return render(request, "observe/upload.html", {"form": InventoryListForm()})
forms.py:
class InventoryListForm(ModelForm):
class Meta:
model = InventoryList
exclude = ['enterprise', 'client', 'engagement', 'stockcount']
def __init__(self, *args, **kwargs):
super(InventoryListForm, self).__init__(*args, **kwargs)
upload_to callable function:
def file_upload_location(instance, filename):
ext = filename.split('.')[-1]
# return f"{instance.enterprise}/{instance.client}/{instance.engagement}/{instance.stockcount}/{filename}"
# return f"{filename}"
FileType = '\\Inventory List'
name = str(filename)
path = os.path.join(str(instance.enterprise), str(instance.client), str(instance.engagement), str(instance.stockcount))
# return f"{path}/{filename}"
# return path
print(f"The path is {path}")
# return f"{path}/"
# return '{0}/{1}/{2}/{3}/{4}'.format(str(instance.enterprise), str(instance.client), str(instance.engagement), str(instance.stockcount), filename)
return os.path.join("%s" % str(instance.enterprise), "%s" % str(instance.client), "%s" % str(instance.engagement), "%s" % str(instance.stockcount), filename)
I have tried multiple variations of the callable functions (as can be seen above from the commented out portions of the function), but I still am getting this error. What is interesting is that when it is the first time I upload the file and submit the form, it works. However, the second time I try, it gives me this errno2 error.
The full traceback is as follows:
[Errno 2] No such file or directory: 'C:\Users\bilal\Desktop\Inventory Observation Mobile Responsive Web Application\Inventory-observation-mobile-responsive-web-application\inventoryobservation\files\1_RSM Canada\PK752_Nuvera Corp\FY 2021_Prospectus work\London Count\Monthly_Sales_Reporting_Template_Tool_Start.xlsm'
It appears as though my actual solutions works for some excel files and not for others, and based on further inspection of the excel files, there doesn't appear to be anything different about the excel files that I am able to successfully upload and the ones that I am not able to upload.
Try to Use this :-
UploadedFile = models.FileField(_('Upload Inventory Listing'), upload_to = 'file_upload_location', validators=[validate_file_extension], max_length = 500)
instead of :-
UploadedFile = models.FileField(_('Upload Inventory Listing'), upload_to = file_upload_location, validators=[validate_file_extension], max_length = 500)
What i've edited :- I have added comas on 'file_upload_location'.
Try to Use it .

Multi-file upload using Django not working as expected

Im having trouble on uploading multiple files. The uploaded files are pdf and only one is saved.
views.py
def attachments(request):
to = TravelOrder.objects.order_by('-date_filling').last()
if request.method == 'POST':
form = AttachmentsForm(request.POST, request.FILES)
if form.is_valid():
for f in request.FILES.getlist('attachment'):
file_instance = Attachements(travel_order=to, attachment=f)
file_instance.save()
print('YEY')
return redirect('attach')
else:
form = AttachmentsForm()
context = {
'form': form
}
return render(request, 'employee/attachments.html', context)
models.py
class TravelOrder(models.Model):
created_by = models.CharField(max_length=255)
start_date = models.DateField(auto_now=False)
end_date = models.DateField(auto_now=False)
wfp = models.CharField(max_length=255, verbose_name='Wfp Where to be charged')
purpose_of_travel = models.CharField(max_length=255)
region = models.ForeignKey(Region, on_delete=models.CASCADE)
venue = models.CharField(max_length=255)
date_filling = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=15)
def __str__(self):
return self.purpose_of_travel
class Attachements(models.Model):
at_id = models.AutoField(primary_key=True)
travel_order = models.ForeignKey(TravelOrder, on_delete=models.CASCADE)
attachment = models.FileField(upload_to='attachment/')
I think you are returing before the loop finishes.
for f in request.FILES.getlist('attachment'):
file_instance = Attachements(travel_order=to, attachment=f)
file_instance.save()
print('YEY')
return redirect('attach')
Take the return outside loop, so that the redirect happens only after saving all files. That means
for f in request.FILES.getlist('attachment'):
file_instance = Attachements(travel_order=to, attachment=f)
file_instance.save()
print('YEY')
return redirect('attach')