Je suis en train de créer un dossier pour chaque utilisateur de mettre leur projet. Ainsi, leur dossier aura le chemin ..\project\id\filename
, id
est l'utilisateur id
et filename
est le nom du fichier. Maintenant, en utilisant les arguments autorisés pour upload_to
(instance
et filename
) dans le Filefield
, je me rends compte que instance.id
seront None
et le chemin vers le fichier sera ..\project\None\filename
au lieu de ..\project\id\filename
.Comment enregistrer un fichier sur un modèle en utilisant upload_to pour les chemins dynamiques
en train de lire la Django documentation upload_to j'ai vu ceci:
Dans la plupart des cas, cet objet aura pas été enregistré dans la base de données encore, donc si elle utilise la valeur par défaut AutoField, il pourrait ne pas encore avoir un valeur pour son champ clé primaire.
Mon interprétation est que la création d'un nouvel enregistrement et user_directory_path
ne sont pas instancié en même temps, c'est, quand je l'appelle create
le modèle Project
, instance.id
seront None
. Ma question est la suivante: y a-t-il un moyen de contourner cela? Bien que je vois upload_to
pratique, il n'est pas nécessairement pratique pour le chemin dynamique comme celui que je fais. Je pensais à créer l'enregistrement, puis ajouter le chemin du fichier dans une mise à jour, mais je suis à la recherche d'un moyen qui peut tout enregistrer en une seule étape.
models.py
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'project/{0}/{1}'.format(instance.user.id, filename)
class Project(models.Model):
email = models.ForeignKey(User,
to_field="email",
max_length=50
)
title = models.CharField(max_length=100)
date_created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
file = models.FileField(upload_to=user_directory_path, validators=[validate_file_type], null=True)
Ceci est views.py
lorsque le formulaire est validé. L'avis user_directory_path
est appelé juste avant le create
.
email = request.user.email
title = request.POST.get('title', '')
file = request.FILES['file']
filename = file.name
instance = Usermie.objects.get(email=request.user.email)
# Save to model
user_directory_path(instance=instance, filename=filename)
Project.objects.create(
title=title, file=file,
)
'Et le bonus est que si l'utilisateur change son adresse e-mail, il changera partout, vous ne devez pas compter sur les mises à jour en cascade pour réparer toutes les clés étrangères.» Très bonne raison d'utiliser 'id' dans ForeignKey. –
Merci! Cela m'a en fait donné un meilleur aperçu. Je vais revenir en arrière et modifier mes champs de courrier électronique dans tous les autres modèles à l'ID utilisateur. Je n'ai pas réalisé le problème des utilisateurs changeant des email jusqu'à maintenant. Merci @MHassan. J'ai toujours su à ce sujet mais n'ai pas réalisé que je le faisais. – Jam1
Je vous remercie de votre aide. L'autre chose que je devrais mentionner est qu'une fois que vous avez créé le projet vous ne pouvez pas permettre à l'utilisateur de changer parce que cela changerait le chemin du répertoire et les fichiers ne seraient plus trouvés par django. –