Ajoutez les modèles du blog et des photos
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 photo
par la relationForeignKey
. Le modèlePhoto
contient 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... OK
Très bien, maintenant que les modèles sont configurés, regardons comment gérer les images mises en ligne par les utilisateurs dans Django.
Mettez en ligne des images avec un formulaire
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 :
Étape 1 : Configurezsettings.py
Pour 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/')
Étape 2 : Ajoutez les médias aux modèles d’URL
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_ROOT
seront servies au chemin donné parMEDIA_URL
.
Étape 3 : Créez un formulaire capable de gérer les mises en ligne d’images
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.py
dansblog/
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']
Étape 4 : Construisez la vue pour qu’elle gère les téléversements d’images
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.FILES
en 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 !
Étape 5 : Ajoutez le gabarit
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.
Étape 6 : Mettez à jour les modèles d’URL
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')
]
Étape 7 : Créez un flux, ou « feed »
Pour voir les photos qui ont été chargées, vous devez les récupérer dans la vue. Refactorisez la vue home
pour 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é url
du champ image
. La propriété url
est construite à partir du paramètre MEDIA_URL
que 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.
C'est à vous ! Mettez en ligne une 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 vue
upload_profile_photo
dans 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 lien
Change 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 passer
request.FILES
àUploadProfilePhotoForm
lorsque vous gérez les donnéesPOST
.
Lorsque vous aurez terminé, comparez votre solution avec la solution sur GitHub.
En résumé
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 unModelForm
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 !