12π
-
I donβt recommend you to use user email or any other information that can be updated as folder name because you wonβt change folder name each time he changes his email or his username. So, use user id that is unique and unchangeable.
-
Here is a complete example from Django documentation, to access instance information in your models to build path with user id :
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)
In this case, it use the user id in the folder name. Of course, your can replaceFileField
with ImageField
.
More information in django docs : FileFields.upload_to
5π
You could maybe separate the folder by their username? You can create a function that would create a folder using the users username like so:
def get_user_image_folder(instance, filename):
return "%s/%s" %(instance.user.username, filename)
and in your model you could easily use the upload_to
and add the function that you just created to it:
class Images(models.Model):
user = models.ForeignKey(User)
image = models.ImageField(upload_to=get_user_image_folder,
verbose_name='Image', )
You donβt have to use request
in Models, you use instance
instead.
- Django β how to get user logged in (get_queryset in ListView)
- Django manage.py runserver verbosity
2π
To get this to work I implemented the solution from the docs as suggested by Louis Barranqueiro, whereby the models looks like:
# models.py
def user_directory_path(instance, filename):
return 'user_{0}/{1}'.format(instance.user.id, filename)
class Document(models.Model):
file = models.FileField(upload_to=user_directory_path)
uploaded_at = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='documents')
But crucially, I also changed my DocumentUploadView class to include a save step, so that the document saves with the user attribute (note also the initial commit=False save step, which is crucial):
# views.py
class DocumentUploadView(View):
def get(self, request):
documents_list = Document.objects.all()
return render(self.request, 'file_upload.html', {'documents': documents_list})
def post(self, request):
form = DocumentForm(self.request.POST, self.request.FILES)
if form.is_valid():
document = form.save(commit=False)
document.user = request.user
document.save()
data = {'is_valid': True, 'name': document.file.name, 'url': document.file.url}
else:
data = {'is_valid': False}
return JsonResponse(data)
Finally my forms.py looks like this:
# forms.py
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ('file',)
- Is a varchar 2 more efficient than a varchar 255?
- Limit Maximum Choices of ManyToManyField
- Django and models with multiple foreign keys
- Django β how to get user logged in (get_queryset in ListView)
- Django backup strategy with dumpdata and migrations
1π
For anyone else in the future that stumble across this, I got access to the current userβs ID by adding the user object to the model in the view.
views.py
from .models import Document
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile=request.FILES['docfile'])
newdoc.owner = request.user
newdoc.save()
Then, in models.py you can retrieve the ID from owner created previously in view.
def user_directory_path(instance, filename):
return 'Users/user_{0}/{1}'.format(instance.owner.id, filename)
class Document(models.Model):
docfile = models.FileField(upload_to=user_directory_path)
- How do I use request.META.get('HTTP_REFERER') within template?
- Django β how to get user logged in (get_queryset in ListView)
0π
In your views.py you must pass the instance argument like this:
def post(self, request, *args, **kwargs):
if 'uploadFile' in request.POST:
f = UploadFileForm(request.POST, request.FILES, instance=request.user.uploadmodel)
if f.is_valid():
f.save()
return HttpResponseRedirect('/sucess_url')
And your forms.py
from django import forms
from .models import UploadForm
class UploadFileForm(forms.ModelForm):
class Meta:
model = UploadForm
fields = ('file',)
- Do I need to close connection in mongodb?
- Django DateTimeField says 'You are 5.5 hours ahead of server time.'
- Resize image maintaining aspect ratio AND making portrait and landscape images exact same size?
- How to render django form field in template
0π
I also faced the same problem. Here is how I solved it. We have to create the user referencing in the view.
Below is the code for models.py
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 Document(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
docfile = models.FileField(upload_to=user_directory_path)
date = models.DateTimeField(auto_now_add=True, blank=True)
Also update the code in views.py as below:
def upload(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile=request.FILES['docfile'],user=request.user)
newdoc.save()
latest_documents = Document.objects.all().order_by('-id')[0]
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('list'))
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.filter(user=request.user)
The most important one is in the line,
newdoc = Document(docfile=request.FILES['docfile'],user=request.user)
Somehow I could not get the model instance to read the user. This approach is working for me.
- Do I need to close connection in mongodb?
- How to append extra data to the existing serializer in django
- How to test a model that has a foreign key in django?
- Django serialize multiple objects in one call