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?
Related
According to this documentation for Vue's SSR, it is possible to use node.js to render an app and return it using an express server. Is is possible to do the same with FastAPI?
Or is using Jinja2 templates or SPA the only solution?
Problems:
No SPA: To help with SEO
No SSG: Too many pages will be generated. Some need to be generated dynamically.
No Jinja2/Python Templates: Node modules aren't built, bundled and served. All modules have to served from a remote package CDN.
I have a feeling that maybe changing the Vue 3 delimiters and then building the project and serving the files as Jinja2 templates is the solution, but I'm not sure how it would work with Vue's routers. I know the /dist folder can be served on the default route and then use a catchall can be used to display files that do exist.
Possible Solution
#app.get("/", response_class=FileResponse)
def read_index(request: Request):
index = f"{static_folder}/index.html"
return FileResponse(index)
#app.get("/{catchall:path}", response_class=FileResponse)
def read_index(request: Request):
path = request.path_params["catchall"]
file = static_folder + path
if os.path.exists(file):
return FileResponse(file)
index = f"{static_folder}/index.html"
return FileResponse(index)
Questions
If there is a way to do SSR with FastAPI and Vue 3, what is it?
If there is no direct way, how do I combine Vue's built /dist with Jinja2 templates to serve dynamic pages?
There are several options available, such as Nuxt.js, Quasar, and Gridsome, which provide support for SSR with FastAPI and Vue 3.
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'])
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.
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.
I'm having trouble associating Soundcloud accounts to user accounts on my app.
The app is built on django using python-social-auth, and I also have a Facebook association, which is working perfectly.
When I click on the soundcloud button, it redirects me to
http://local.gl.com:8080/?error=redirect_uri_mismatch&error_description=The+redirection+URI+provided+does+not+match+a+pre-registered+value.&state=OBclf3I3ODoKKD5uRdD97AozInK1iUF2#
and nothing happens.
local.gl.com is mapped to my development server address on /etc/hosts
my redirection URI on the soundcloud developers page is
http://local.gl.com:8080/ and on my settings.py I have:
SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/users/register/'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'
On the .html file I have
soundcloud
Which is basically the same thing I'm using for Facebook, which is working.
I've tried everything that I could find on SO, including registering a new app with soundcloud but I always get the same error.
Any suggestions?
I just had to change the redirect URI on soundcloud page to
http://local.gl.com:8080/complete/soundcloud/
I had already tried that but I had a different error on the settings.py that I hadn't realised, so I was also getting an error with that uri