Próbuję ustawić przesyłanie tak, aby jeśli użytkownik joe prześle plik, trafił do MEDIA_ROOT / joe, w przeciwieństwie do wszystkich plików, które mają trafiać do MEDIA_ROOT. Problem w tym, że nie wiem, jak to zdefiniować w modelu. Oto jak to obecnie wygląda:
class Content(models.Model):
name = models.CharField(max_length=200)
user = models.ForeignKey(User)
file = models.FileField(upload_to='.')
Więc to, czego chcę, to zamiast „”. jako upload_to, niech to będzie nazwa użytkownika.
Rozumiem, że od Django 1.0 możesz zdefiniować własną funkcję do obsługi upload_to, ale ta funkcja nie ma pojęcia, kim będzie użytkownik, więc jestem trochę zagubiony.
Dzięki za pomoc!
python
django
django-models
Teebes
źródło
źródło
os.path.join
zamiast,'/'.join
aby upewnić się, że działa również na systemach innych niż Unix. Mogą być rzadkie, ale to dobra praktyka;)To naprawdę pomogło. Dla większej zwięzłości zdecydowałem się w moim przypadku na lambdę:
file = models.FileField( upload_to=lambda instance, filename: '/'.join(['mymodel', str(instance.pk), filename]), )
źródło
pk
przed zapisaniem. Działa tylko w przypadku aktualizacji, a nie kreacji (wstawek).migrations
operacjach, ponieważ nie można jej serializować zgodnie z dokumentacjąUwaga dotycząca używania wartości pk obiektu „instancja”. Zgodnie z dokumentacją:
Dlatego ważność użycia pk zależy od tego, jak zdefiniowany jest twój konkretny model.
źródło
Jeśli masz problemy z migracjami, prawdopodobnie powinieneś użyć
@deconstructible
dekoratora.import datetime import os import unicodedata from django.core.files.storage import default_storage from django.utils.deconstruct import deconstructible from django.utils.encoding import force_text, force_str @deconstructible class UploadToPath(object): def __init__(self, upload_to): self.upload_to = upload_to def __call__(self, instance, filename): return self.generate_filename(filename) def get_directory_name(self): return os.path.normpath(force_text(datetime.datetime.now().strftime(force_str(self.upload_to)))) def get_filename(self, filename): filename = default_storage.get_valid_name(os.path.basename(filename)) filename = force_text(filename) filename = unicodedata.normalize('NFKD', filename).encode('ascii', 'ignore').decode('ascii') return os.path.normpath(filename) def generate_filename(self, filename): return os.path.join(self.get_directory_name(), self.get_filename(filename))
Stosowanie:
class MyModel(models.Model): file = models.FileField(upload_to=UploadToPath('files/%Y/%m/%d'), max_length=255)
źródło