Thanks, that was very helpful. I had another pointer on this and
found out that the easiest way to do this is just to change the
```file``` line in the class to:
```
file = ImageField(_('image'), upload_to='images/items/%Y/%m/%d/%
H/%M/%S')
````
There are a few things that I do not understand, however, after
playing around with some code for a while.
If I just pass a string to ```file``` it understands that this is a
partial path, and it has to stick ```filename``` on the end. eg:
```file = ImageField(_('image'), upload_to='images/items')```
Likewise with the version above with the date formatting.
This is also the case when I used my initial ```upload_path```
function, calling it with ```upload_to=upload_path()``` – but this
did not suit the task, because ```upload_path``` loaded at
initialisation of the server.
So, given that ```upload_path``` returns a string, I don't understand
why I also have to concatenate the ```filename```:
```
def upload_path(instance, filename):
dtnow = datetime.now(timezone.utc)
dtstr = '{:%Y/%m/%d}'.format(dtnow)
dtstr = 'images/items/' + dtstr + '/' + filename
return dtstr
```
In this case, if I do not concatenate ```filename``` then the
uploaded file gets named with the last element of the date formatting
and without a file extension, ie potentially like this:
```images/items/2020/10/28/20/59/55```
rather than:
```images/items/2020/10/28/20/59/55/image.jpg```
The other thing I don't understand is how ```instance``` and
```filename``` are passed to the function ```upload_path```. I would
expect to do something like:
``` file = ImageField(_('image'), upload_to=upload_path(instance,
filename))```
But if I do that I get:
```NameError: name 'instance' is not defined```
Sorry for so many more questions!
-- Clive
On 28 Oct 2020, at 08:58, Carles Pina i Estany wrote:
Hi,
On Oct/27/2020, Clive Bruton wrote:
I have a function that uses the current date to set up a file path
for
uploaded images:
********************
def upload_path():
[...]
class Image(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
#file = ImageField(_('image'), upload_to='images')
file = ImageField(_('image'), upload_to=upload_path())
The problem is that when the Image class calls 'upload_path' the
datetime portion of this is always the runserver initialisation time,
rather than the time when 'upload_path' is called/used.
How to fix this?
For what I remeber (I use FileField usually but this is noto
relevant I
hope) you should do:
def upload_path(instance, filename):
# you have access to the instance (object model Image in your
case)
# and the filename that the user used to upload it
# and this is executed on the upload time
return your_new_file_name
In the model:
file = ImageField(_('image'), upload_to=upload_path)
note that upload_path is a callable: it gets called on the upload
time.
In your code it was called on initialization time.
Some time ago I had a similar code that caused a bug: in a ListView
the
"queryset = " is executed on startup time. For a dynamic one I should
have used get_queryset() method.
--
Carles Pina i Estany
https://carles.pina.cat
--
You received this message because you are subscribed to the Google
Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to [email protected].
To view this discussion on the web visit https://groups.google.com/
d/msgid/django-users/20201028085843.GA20091%40pina.cat.
--
You received this message because you are subscribed to the Google Groups "Django
users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/2FBF21DA-2057-4302-BED8-629F9C835337%40indx.co.uk.