Django MEDIA_ROOT pointed to network drive - python

I'm trying to get files uploaded through the Django admin site to be placed on a network drive. Lets say the path to this drive is '\\FILESERVER\Django'.
My initial thought was to just set my media root to the same path I'd use to access the drive via File Explorer:
#settings.py
MEDIA_ROOT = r'\\FILESERVER\Django'
An Example Model:
#models.py
class Article(models.Model):
title = models.CharField(max_length=128)
pdf = models.FileField(upload_to='articles', blank=True, null=True)
def __str__(self):
return self.title
But when I upload a file, It just creates the folder on my local C: drive.
(e.g. C:\FILESERVER\Django\articles). Is there a way I can tell Django that this is supposed to be a path to a network drive?
Note: This is a Django 2.0.4 app running on a windows machine.

I believe what you're looking for is in pathlib. Have a look here:
https://docs.python.org/3/library/pathlib.html#methods-and-properties
Something like PureWindowsPath('//FILESERVER/Django').drive should do the trick for MEDIA_ROOT, IIRC.

If you use a network file server,you may need a customized django file storage class.

Related

Django upload and download files in google drive using googledriveapi

I am new to django and trying to create a web app to upload and download files to the google drive using gdriveapi.
I have gone through the python quickstart for Google drive and tried the code in manage.py where it is working.
How to write the same code to obtain credentials and upload and download in the django app?
How to write the view and model in django to obtain credentials and upload files to gdrive?
for my model field I use file = models.FileField(upload_to='todo', storage=gd_storage, blank=True, null=True), where todo is the app name. For the view I simply used the generic ModelViewSet, where you can just serializer.save(file=self.request.data['file'])

Cannot locate local path of uploaded file to Heroku from django using ephemeral file system( Web based Application)

I have recently deployed my first django project to Heroku. My project is a Web Based Application that allows users to upload a file to the server and the server will export a product after processing it.
The views.py processing the upload process is as follows
if form.is_valid():
task= form.save(commit=False)
task.task_created_by = request.user
task.save()
The model is as follows
class db(models.Model):
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
description = models.CharField(max_length=255, blank=True)
excel = models.FileField(upload_to='task/excel/')
userinput = models.FileField(upload_to='task/userinput/')
output= models.FileField(blank=True,null=True)
uploaded_at = models.DateTimeField(auto_now_add=True)
settings.py
#Media path setting
MEDIA_URL = '/uploaded/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploaded')
Therefore, a part of the server involves accessing the user uploaded file and thus processing it.
I did not set up any external file storage service(e.g. aws s3) and is only using the default ephemeral file system.
when I first run the application the server response this error
No such file or directory: '/app/uploaded/task\\excel\\abc.xlsx'
However, as I am using the django model file field, when I go to the django admin panel, it shows the file is uploaded and can be downloaded from the admin panel...
Therefore, the question is where did Heroku saved the uploaded file locally...
I have tried the heroku run bash method to search for the file but with no luck...
Any help would be appreciated, many thanks!!

django-tenants: access tenant media files in script

I am running an app built with djang-tenants. The app asks the user (tenant) to upload some data. I want the data to be segregated in sub directories for each tenant.
Acccording to the doc (https://django-tenants.readthedocs.io/en/latest/files.html), here is how media root is configured:
settings.py
MEDIA_ROOT = "/Users/murcielago/desktop/simulation_application/data"
MULTITENANT_RELATIVE_MEDIA_ROOT = "%s"
On the upload everything is great.
Now, I can't find a way to retrieve the file being uploaded within the app. Basically I need the app to serve the file corresponding to which tenant is requesting it.
Here is how I thought this would work:
from django.conf import settings
media_file_dir = settings.MULTITENANT_RELATIVE_MEDIA_ROOT
df = pd.read_csv(media_file_dir+'/uploads/sample_orders_data.csv')
but this does not work.
I have made it work so far grabbing the tenant name from the url and passing it to the app using pickle but this is not right in terms of security and won't scale.
Would someone has a clue on the best way to handle the lecture of tenant specific files?

How to auto-upload an image from django app to aws s3

When a user creates or registers for a new account on my website, an image is created(generated) and is supposed to be uploaded to the s3 bucket. The image is successfully created(verified by running the ls command on the server in the media directory) but it's not getting uploaded to s3. However, when I try uploading an image for a user account from the admin panel, changes are correctly reflected in s3 (i.e newly uploaded image from admin panel is shown in s3 bucket's directory, but this is not feasible as the users cannot be given admin panel access). I aim to auto-upload the generated image to the s3 bucket when a new account is created.
Here's some related code.
views.py
def signup(request):
if request.method == "POST":
base_form = UserForm(data=request.POST)
addnl_form = AddnlForm(data=request.POST)
if base_form.is_valid() and addnl_form.is_valid():
usrnm = base_form.cleaned_data['username']
if UserModel.objects.filter(user__username=usrnm).count()==0:
user = base_form.save()
user.set_password(user.password)
user.save()
#print(img)
addnl = addnl_form.save(commit=False )
addnl.user = user
img = qr.make_image() #create a qr code image, full code not included.
img.save('media/qrcodes/%s.png'%usrnm)
addnl.qr_gen = 'qrcodes/%s.png'%usrnm
addnl.save()
else:
messages.error(request,base_form.errors,addnl_form.errors)
else:
base_form = UserForm()
addnl_form = AddnlForm()
return render(request,'app/signup.html',{'base_form':base_form,'addnl_form':addnl_form} )
models.py
class UserModel(models.Model):
.
.
.
qr_gen = models.ImageField(upload_to='qrcodes',default=None,null=True,blank=True)
settings.py
DEFAULT_FILE_STORAGE = 'project.storage_backend.MediaStorage'
storage_backend.py
from storages.backends.s3boto3 import S3Boto3Storage
class MediaStorage(S3Boto3Storage):
location = 'media'
default_acl = 'public-read'
file_overwrite = False
UPDATE
Instead of auto-generating, an image and uploading it to s3, if I upload any image in the registration form, even in that case it's successfully uploading to s3, the only case where it fails is when I need to auto-upload without user intervention.
Please help me solve this problem. Thank you.
I would recommend taking a look at django-storages which automates all of this so you should only worry about the form and the view instead of anything else. In there you will find help on how to deal with images easily.
Instead of globally setting media storage settng, set it on the field
class UserModel(models.Model):
...
qr_gen = models.ImageField(upload_to='qrcodes',storage=MediaStorage())
Auto uploading an image directly to s3 requires one to directly communicate with S3's backend API. Plainly using django-storages or tweaking DEFAULT_FILE_STORAGE path isn't just enough as it only helps to point user-uploaded files to the specified s3 bucket/path. This problem can be tackled using the boto3 library's upload_file method.
Usage example:
import boto3
s3 = boto3.resource('s3')
s3.Bucket('mybucket').upload_file('/tmp/hello.txt', 'hello.txt')
Params:
Filename (str) -- The path to the file to upload.
Key (str) -- The name of the key to upload to.
ExtraArgs (dict) -- Extra arguments that may be passed to the client operation.
Callback (function) -- A method which takes a number of bytes transferred to be periodically called during the upload.

Django Rest framework: I want my GET response to be a JSON object of links to all files in my media directory on my local machine. How do i do this?

My Project structure:
myproject
--*
--*
--media
--*
--*
I want to allow users to access to my media directory: I want them to be able to read and download all files in my media directory and I want them to be able to write files to my media directory.
How can I accomplish this using Django rest framework?
Assume that there are 2 files in my media directory: I want to return the following JSON object as a response to a GET request:
{
file1: link_to_example1.txt
}
{
file2: link_to_example2.txt
}
How do I do this -- what should my app's model.py, views.py and maybe serializers.py look like?
We can start with simple thing like this. Every time user upload a file, one record is created in the model. If you plan to add/remove file without using your system, you may need a method to sync the latest folder content with your model's records.
class MediaFile(models.Model):
media_file = models.FileField()
uploaded = models.DateTimeField(auto_now_add=True)
class MediaFileSerializer(serializers.ListSerializer):
class Meta:
model = MediaFile
fields = ('media_file',)
class MediaViewSet(viewsets.ViewSet):
"""
A simple ViewSet for listing or retrieving MediaList.
"""
serializer_class = MediaFileSerializer
Then you can study how to upload file with Django and DRF.

Categories