Django Admin - Create 'temporary' entry - django

Is there a way to make it so the Django Admin panel creates a temporary model when you click the "add" button?
I want to be able to 'attach' multiple files / media to a particular model entry which would involve uploading the files at the time of creation. I can't do this until the model has a pk as obviously I can't create a link between the uploaded file and the entry.
I am using the Content-Type framework to create the attachment between my uploaded file (which is wrapped in a class)
I noticed that Wordpress for example creates what is called an 'auto draft' when you click the "new post" button to get around problem.

If I understand correctly, you want to take care that the filename of your uploaded file corresponds with the model's PK where the file-fields are used.
There is nothing you must change in the django-admin, but make some adjustions on your model:
First, make use of "upload_to" in your filefield. I usually set the filename to a uuid4-value to make sure it's unique.
After saving the model, you can rename the file if you want. The best place is in a function that is triggered by a post-save-signal. But if you only want to ensure, that the filename is unique, the filename-generation by uuid should work.

Related

Accessing url of ImageField via values() method on django queryset

I have a data model in Django where I save photos uploaded by users. There's an attribute called image_file in the Photo model (of the type ImageField) where - among other things - the image's url is stored. I can successfully access this url with item.image_file.url in the template (and view) for instance.
However, I can't seem to be able to do the following in the view:
Photo.objects.filter(owner=user).order_by('-id').values('id','image_file.url')[:10]
I.e. For a particular user, I'm trying to get the 10 latest photo objects' image urls along with object ids. This gives me FieldError: Cannot resolve keyword 'image_file.url' into field. Shouldn't this have worked?
I understand I can retrieve the entire object and do the filtering in the template, but I felt it's more optimal to solely retrieve the fields I actually need instead of the full object.
p.s. it's a postgresql backend and the underlying Storage class has been over-ridden
The url is a property, not a value in the database (FileField code) which is why you can't get to it from values(). As far as I can see, you'd have to get the url value separately...
You might want to take a look at only() though. If you go that route, you should probably watch the SQL queries with something like Django Debug Toolbar. If the url property tries to retrieve a field that wasn't included in only(), it will likely make a separate SQL call.

django admin uploaded file processing

Here's what I want to do, and I did not find something similar in my search so far.
In my admin page, I have a Filefield in my model. The rest of the fields are all read only.
I want to be able to upload a file and process it immediately and to extract info from it to assign to these read only fields.
I thought of overriding the clean_(modelfield) method for this FileField and do this parsing and assigning stuff in it. But this is not done right after the file is uploaded, right? I thought this is done when the form/entry is saved.
Next I thought of adding a custom button to this admin form called 'process' which can be clicked after the file is uploaded. This would trigger the assignment of values to the read only fields.
But I am not able to decide on what is the best approach to process the file and display the updated fields in one page without too much of tinkering.
Any thoughts? Thanks
There are two solutions that I can think of with my limited knowledge. Since, by default, the file upload will only start once the request is posted, an alternative way needs to be designed.
1. Upload file via a script and process the file: Use a script (eg: JQuery script) to upload the file and once upload is complete, trigger a script (onComplete event) to render the values into read-only field. This entire process can be associated to your "Process" button or a time-delayed trigger once the FileField is changed.
2 Custom form for file upload: You can detach the file field and other fields (read only fields that you mentioned). If you design a custom form with just the file upload field and once the user submits the request, you can render another form with rendered initial values in the read only fields. That way you need not have any script but you will have to have 2 forms.
Hope this helps. If you find any other solution, do share it :)

Prompt a confirmation page for a form with FileInput field in Django

I'm developing an admin interface (without a model) for a data restore process. The form on the page allows user to upload a restore file. Now, what I'd like to do is, when the user submit the form, I want to upload the file first, pre-process it, then show a confirmation page to user.
In the pre-process, assuming the form is valid, I unpackage the restore file and extract the backup time from it, then show the backup time (and possibly other information from the restore file) to user in the confirmation page.
My problem is I don't know what the best way is to save the file state. Ideally I'd like to pass the uploaded file to the confirmation page form then when user agrees to continue, I use the restore file to actually restore the system. However, I can't seem to figure out how to do it.
So what I did was to save the file first, then somehow include the filepath in the confirmation page in a hidden field. However, there's a security risk by doing this since the filepath can be modified when user submits the confirmation form.
What's the best way to tackle this problem?
Thanks!
Store the filepath location in the session. You can access the session from your view:
def your_view(request):
...
request.session['file_path'] = 'the file path'
Then in another view get it out:
def your_other_view(request):
...
request.session.get('file_path')
and pass it to your template for use.
You don't have to worry about security, (from the Django docs):
It stores data on the server side and abstracts the sending and receiving of cookies. Cookies contain a session ID – not the data itself.
I tend to solve this problem using a model, that keeps track of a file, and when it was last updated/uploaded. That way in your hidden input you can embed an ID you retrieve later - so if an attacker wants to mess with your form field, all they're going to get is a different backup file (and you could probably write extra validation to handle that).
I'd recommend you create a temporary model to handle your file for you, and then just delete it when you're done processing the file (at the end of the second step).

sorl-thumbnail not deleting parent file or cache when entry is deleted

I'm not sure what I am doing wrong. But the uploaded file and it's related cache don't get deleted when the entry is deleted.
I have a photos model inline of a property model, with an FK from the photos model to the property model. I am using 'from sorl.thumbnail import ImageField' to replace the default Django models.ImageField.
In Django Admin, when I delete the entry of a photo, the entry is deleted but the files for that entry are not deleted. I am using Django's runserver for the development and I am not seeing any errors. From what I have read, these files should be removed if the entry is deleted, unless there is a reference to them yet. The only reference that I am seeing yet is in the thumbnail_kvstore table.
Anyone have any thoughts on what I am missing?
The delete_file method will only be called in Django < v1.2.5. The best way to delete sorl.thumbnail.ImageField files, thumbnails and key value store references (used by sorl thumbnail) is to use sorl.thumbnail.delete function: sorl.thumbnail.delete(self.photo)
The ImageField from sorl.thumbnail should be an extension of django's FileField
From the release notes of django 1.2.5:
In earlier Django versions, when a model instance containing a FileField was deleted, FileField took it upon itself to also delete the file from the backend storage. This opened the door to several potentially serious data-loss scenarios, including rolled-back transactions and fields on different models referencing the same file. In Django 1.2.5, FileField will never delete files from the backend storage. If you need cleanup of orphaned files, you'll need to handle it yourself (for instance, with a custom management command that can be run manually or scheduled to run periodically via e.g. cron).
I had the problem with django-filebrowser, and when you replaced the image with a new one, the cached files did not update. So in my case it wasn't an issue with sorl-thumbnail but rather with django-filebrowser. sorl would only re-draw the thumbnails when the path of the file changed. To fix this I set the filebrowser FILEBROWSER_OVERWRITE_EXISTING setting to False.
FILEBROWSER_OVERWRITE_EXISTING = False
This may help someone at least debug the issue if they are not using django-filebrowser. But in the case of django-filebrowser this is the way to go. Cheers.

Django admin action with file upload - process file content and put it in database

I want to add some functionality in admin that allows me to upload file and then process it.
I already have a model that I can edit trough the admin, but I want to be able to "upload" multiple items with this file processing.
How can I achieve this in the admin?
you can use Django Filebrowser. This app can handle multiple uploads with progressbar and have many other things.
The solutions I used is the one described in my comment. Create an empty model (with pass instead of fields), custom admin form and place your logic in the form.