Notre but ultime est de construire un flux qui contiendra des billets de blog et des photos partagés par les créateurs auxquels un utilisateur s’est abonné.
Néanmoins, avant de pouvoir faire cela, nous devons ajouter les modèles qui représenteront ces billets de blog et ces photos, puis nous devons donner aux utilisateurs les moyens de les créer. Découvrez dans la vidéo ci-dessous comment ajouter une page qui permettra aux utilisateurs de mettre en ligne des fichiers.
Commençons par les modèles. Tous nos changements concernent désormais l’application blog, donc ajoutons ce qui suit à blog/models.py :
# blog/models.py
from django.conf import settings
from django.db import models
class Photo(models.Model):
image = models.ImageField()
caption = models.CharField(max_length=128, blank=True)
uploader = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True)
class Blog(models.Model):
photo = models.ForeignKey(Photo, null=True, on_delete=models.SET_NULL, blank=True)
title = models.CharField(max_length=128)
content = models.CharField(max_length=5000)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True)
starred = models.BooleanField(default=False)Comme vous pouvez le constater, les billets de blog peuvent, de façon optionnelle, être liés à une photopar la relationForeignKey. Le modèlePhotocontient une image stockée dans le ImageField .
Générons et exécutons les migrations.
(ENV) ~/fotoblog (master)
→ python manage.py makemigrations
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model Photo
- Create model Blog
(ENV) ~/fotoblog (master)
→ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, authentication, blog, contenttypes, sessions
Running migrations:
Applying blog.0001_initial... OKTrès bien, maintenant que les modèles sont configurés, regardons comment gérer les images mises en ligne par les utilisateurs dans Django.
Avant de mettre en ligne des images dans Django, vous devez configurer l’emplacement où stocker le contenu média. Dans ce cas, le contenu média correspond aux fichiers et images qui sont mises par les utilisateurs. Configurons maintenant notre application afin de gérer les fichiers mis en ligne par les utilisateurs sur notre site. Voici la procédure en vidéo :
settings.pyPour ce faire, vous devez configurer deux valeurs danssettings.py.
Premièrement, MEDIA_URL , qui est l’URL depuis laquelle Django va essayer de servir des médias. Dans certains cas, ce peut être une URL complète vers un autre hôte, si vous utilisez un service tiers pour servir vos médias.
Pour cette classe, vous allez servir les images en local. Vous pouvez donc fournir un chemin qui pointe vers votre serveur local.
Le deuxième paramètre à configurer est MEDIA_ROOT. Il indique le répertoire local dans lequel Django doit sauvegarder les images téléversées.
Voici la configuration à ajouter :
# fotoblog/settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR.joinpath('media/')Vous devez maintenant mettre à jour vos modèles d’URL, de sorte que le média mis en ligne soit accessible par le biais d’une URL.
Pour ce faire, ajoutez :
# fotoblog/urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
...
]
if settings.DEBUG:
urlpatterns += static(
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)Désormais, les images stockées dans le répertoireMEDIA_ROOTseront servies au chemin donné parMEDIA_URL.
Maintenant que les paramètres sont configurés, ajoutons un formulaire pour mettre en ligne les photos.
C’est très facile à faire. Vous pouvez utiliser un ModelForm , et Django gérera le transfert du fichier et l’enregistrera dans le système de fichiers pour vous.
Créons un fichierforms.pydansblog/ et ajoutons les lignes suivantes :
# blog/forms.py
from django import forms
from . import models
class PhotoForm(forms.ModelForm):
class Meta:
model = models.Photo
fields = ['image', 'caption']Et maintenant, ajoutons la vue. D’habitude, on remplit un formulaire uniquement avec l’objet request.POST. Ici, vu que vous transférez une image, vous devez aussi lui donner tout fichier envoyé avec la requête. Faites-le en passant égalementrequest.FILESen argument.
Nous voulons assigner au champ uploader de la Photo l’utilisateur connecté à ce moment-là. Vous pouvez créer l’objet Photo sans le sauvegarder dans la base de données, en enregistrant le formulaire avec l’argumentcommit=False . Ensuite, assignez la valeur correcte à uploader, et enfin, sauvegardez le modèle pour le stocker dans la base de données.
# blog/views.py
from django.shortcuts import redirect, render
from . import forms
@login_required
def photo_upload(request):
form = forms.PhotoForm()
if request.method == 'POST':
form = forms.PhotoForm(request.POST, request.FILES)
if form.is_valid():
photo = form.save(commit=False)
# set the uploader to the user before saving the model
photo.uploader = request.user
# now we can save
photo.save()
return redirect('home')
return render(request, 'blog/photo_upload.html', context={'form': form})Mettre l’image en ligne est facile, car c’est le ModelForm qui fait le gros du travail !
Ajoutons le gabarit.
# blog/templates/blog/photo_upload.html
{% extends 'base.html' %}
{% block content %}
<h2>Télécharger une photo</h2>
<form method="post" enctype="multipart/form-data">
{{ form.as_p }}
{% csrf_token %}
<button type="submit" >Publier</button>
</form>
{% endblock content %}Notez l’ajout de l’attribut enctype="multipart/form-data" à la balise <form> . C’est obligatoire pour que le formulaire puisse gérer l’envoi de fichiers.
Maintenant, ajoutez la vue aux modèles d’URL.
# fotoblog/urls.py
import blog.views
urlpatterns = [
...
path('photo/upload/', blog.views.photo_upload, name='photo_upload')
]Pour voir les photos qui ont été chargées, vous devez les récupérer dans la vue. Refactorisez la vue homepour le faire.
# blog/views.py
from . import models
@login_required
def home(request):
photos = models.Photo.objects.all()
return render(request, 'blog/home.html', context={'photos': photos})Ensuite, mettez à jour le gabarit. Vous pouvez obtenir le chemin de la photo depuis la propriété urldu champ image. La propriété url est construite à partir du paramètre MEDIA_URLque nous avons configuré précédemment.
# blog/templates/blog/home.html
{% extends 'base.html' %}
{% block content %}
<h2>Photos</h2>
{% for photo in photos %}
<img src="{{ photo.image.url }}">
<p>{{ photo.caption }}</p>
{% endfor %}
{% endblock content %}Bien joué ! Testons maintenant la nouvelle fonctionnalité.
Tout d’abord, mettez en ligne une nouvelle photo.

Ensuite, vérifiez le flux.

C’est gagné ! Les utilisateurs peuvent désormais mettre en ligne leurs photos et les voir dans le flux.
Ensuite, vous allez ajouter une fonctionnalité permettant à un utilisateur de mettre à jour sa photo de profil.
Vous voulez permettre aux utilisateurs de mettre en ligne et d’afficher des photos de profil.
À ces fins, vous allez construire un service de mise en ligne de photo de profil.
Nous avons construit une version mise à jour du site, en soignant le design. Voyons à quoi elle ressemble.

Plutôt classe !
Le design est en CSS. Si vous le souhaitez, vous pouvez maintenant prendre un peu de temps pour soigner le style de votre site avec votre propre design. Ou le récupérer depuis le dépôt GitHub pour inclure les changements sur votre site.
Vous verrez que votre profil utilisateur s’affiche maintenant à gauche de la page, avec le lien « Changer la photo de profil » en dessous.
Pour le moment, ce lien ne fait rien. Pour le faire fonctionner, vous allez devoir :
Créer un formulaire UploadProfilePhotoForm dansauthentication/forms.py — ça peut être unModelForm pourUser.
Créer une vueupload_profile_photodans l’applicationauthentication et configurer la vue pour mettre à jour la photo de profil de l’utilisateur.
Créer un gabarit pour cette vue et ajouter la vue aux modèles d’URL.
Envoyer vers la page avec le lienChange Profile Photo.
Afficher la photo de profil de l’utilisateur dans le profil utilisateur s’il a chargé une photo de profil. Sinon, afficher la photo de profil par défaut. Vous pouvez vérifier ceci avec {% if user.profile_photo %} .
Si vous bloquez :
Vérifiez que vous passez instance=request.user à votreUploadProfilePhotoForm pour mettre à jour l’utilisateur connecté.
Incluez enctype="multipart/form-data"> dans votre balise<form> .
N’oubliez pas de passerrequest.FILES à UploadProfilePhotoForm lorsque vous gérez les donnéesPOST .
Lorsque vous aurez terminé, comparez votre solution avec la solution sur GitHub.
Vous pouvez définir les constantes MEDIA_x dans les paramètres, pour configurer l’emplacement où Django stockera les fichiers chargés par les utilisateurs.
L’ ImageField vous permet de mettre en ligne des images sur le serveur avec un ModelForm
Maintenant que vous savez permettre à des utilisateurs de mettre en ligne leurs propres médias dans une vue, le moment est venu de gérer des formulaires multiples sur une seule page !