Professional Documents
Culture Documents
Revision Django
Revision Django
Revision Django
● Creation Projet:
Settings.Py f lekher
10. MEDIA_URL ='media/' # houni media/ yaani les fichiers w ila images ... yethatou f west media w
ena deja fel model 7atyt images yaani taswira tetsed f west dossier /media/images
11. MEDIA_ROOT ='media/'
12. AUTH_USER_MODEL = "users.Person" # pour specifier le model utilisateur
13. LOGOUT_REDIRECT_URL="login" # pour que lorsque l'utilisateur se deconnecte ou il va
rediriger
14. urls.py
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
par defaut kol model aandou clé primaire ID:w ena najem
nbaddlou(cin=models.CharField(primary_key=True,max_length=8,Validators=[cin_valid]))
kol menajouty model lezmou yerity mel models.model pour que notre model aura toutes les
fonctionnalités et les comportements fournis par la classe Model
fel user me3mlthech khater deja l user yerity mel abstractUser w l abstract user deja terity mel
models.model
class Participation(models.Model):
event = models.ForeignKey(Event,
on_delete=models.CASCADE)
person = models.ForeignKey(Person,
on_delete=models.CASCADE)
participation_date =
models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ('person', 'event')
3. Erreur Migration:
● nthabbet eli les attribiuts lkol maktoubin b minuscule
w nfassakh dossiers migration mes les 2 applications
mte3i events, users,w nfassakh dbsql mte3i
● n3awed les commanses de migrations
)
category = models.CharField('category', choices=Choix,
Amdouni Mouna 4 Twin 6
max_length=8)
state = models.BooleanField(default=False)
#
nbe_participant=models.IntegerField(default=0,validators=[valid_nbe
_participant])
nbe_participant = models.IntegerField(default=0, validators=[
MinValueValidator(limit_value=0, message="le nombre doit etre
positif")])
evt_date = models.DateField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# relation *--1 bin l person w event , kol event yorganiziha person
wehed w w plusieurs persons ynajmou yahdhrou
# f event evenemnt lié ken l person wheed
organizer = models.ForeignKey(Person,
on_delete=models.CASCADE)
# relation *--* bin l person w event / related_name=hiya esm l
relation bin l person w event==>
# Person.participations=+> lesm fel person
participations = models.ManyToManyField(Person,
related_name="participations", through='Participation')
class Meta:
constraints = [
models.CheckConstraint(
check=models.Q( # Q yaani bech nasna3 requete
evt_date__gte=date.today() # >=
),
name="the event date is invalid" # nom Contrainte
)
]
# Classe Poteuse
class Participation(models.Model):
# participation lié l event wahda
event = models.ForeignKey(Event, on_delete=models.CASCADE)
# participation lié ken l person whed
person = models.ForeignKey(Person, on_delete=models.CASCADE)
participation_date = models.DateTimeField(auto_now_add=True)
# houni class Meta sta3mltha lel unicité yaani fel base nal9ach f
classe Participation nafs les donnees m3awdin
# kol person ynajem yparticipi mara khw l evenement wahda mouch
barcha marrta
# yaani il suffit 3mal participation wahda khw meaach ynajem
class Meta:
unique_together = (person , event )
● Contraintes
Amdouni Mouna 4 Twin 6
clé primaire de 8
caractères Fonction de validation:
def cin_valid(val):
if len(val) != 8:
raise ValidationError("La longuer doit etre egal a 8")
return val
cin=models.CharField(primary_key=True,max_length=8,Validators=[cin_valid])
Email
Fonction de validation:
def email_valid(val):
if str(val).endswith('@esprit.tn')==False:
raise ValidationError('Email doit se terminer par @esprit.tn')
Email=models.EmailField(Validators=[email_valid])
Champs unique
username = models.CharField(unique=True,max_length=255)
Champs obligatoire
blank=false et doit Fonction de validation:
commencer par def valid_Title(title):
majuscule if not title[0].isupper():
raise ValidationError("titre doit commencer par une majuscule")
title=models.CharField(max_length=255,blank=False,validators=[valid_Title])
Amdouni Mouna 4 Twin 6
Champs
Multilignes
Description=models.TextField()
Images
Choix liste
deroulante
Choix=(
('Musique','Musique'),
('Cinema','Cinema'),
('Sport','Sport'),
)
category=models.CharField('category',choices=Choix,max_length=8)
Champs boolean
state=models.BooleanField(default=False)
Nombre Positif
, par defaut=0 Fonction de validation:
def valid_nbe_participant(val):
if not val<0:
raise ValidationError("nombre doit etre positif")
# nbe_participant=models.IntegerField(default=0,validators=[valid_nbe_participant])
nbe_participant=models.IntegerField(default=0,validators=[MinValueValidator(limit_value
=0,message="le nombre doit etre positif")])
Amdouni Mouna 4 Twin 6
Created_at
Updated_at
created_at=models.DateTimeField(auto_now_add=True)
updated_at=models.DateTimeField(auto_now=True)
Definition date
doit etre > de la
date
d’aujourd’hui evt_date=models.DateField()
dans la classe class Meta:
constraints=[
Meta models.CheckConstraint(
check=models.Q( #Q yaani bech nasna3 requete
evt_date__gte= date.today() # >=
),
name="the event date is invalid" # nom Contrainte
)
]
En résumé, la classe Meta est utilisée pour fournir des métadonnées supplémentaires au
modèle, tandis que les méthodes de validation personnalisées sont utilisées pour effectuer des
vérifications spécifiques sur les données du modèle.
Amdouni Mouna 4 Twin 6
● Generation Admin:
@admin.register(Person): decorateur
set_to_Refuse.short_description = "Refuse"
def set_toaccept(self, request, queryset):
rows_Valid=queryset.filter(state=True)
if rows_Valid.count() > 0:
messages.error(
request, f"{rows_Valid.count()} events are alread marked accepted"
)
else:
rows_updated= queryset.update(state=True)
if rows_updated ==1:
message = "1 event was "
else :
message= f"{rows_updated} events were"
self.message_user(request, level="success",
message="%s succesfully marked as accepted" %message
)
set_toaccept.short_description="Accept"
actions = [set_to_Refuse,set_toaccept]
Pagination list_per_page= 1
return queryset.filter(evt_date__exact=datetime.today())
class eventAdmin(admin.ModelAdmin):
…
autoComplete autocomplete_fields=['organizer']
('About' ,
{ 'classes' :('collapse',),
'fields' :('title','Description','image','category','nbe_participant','organizer')
}
),
('Dates',
{ 'classes' :('collapse',),
'fields' :('evt_date','updated_at','created_at')
}
)
)
nzidhaja okhra ghir gestion mte3 les evenements w m3aha fard espace (fard
fichier fel event)
@admin.register(Participation)
class participationAdmin(admin.ModelAdmin):
list_display = ('participation_date', 'event', 'person')
list_filter = ('participation_date', 'event', 'person')
ordering = ('participation_date', 'event', 'person')
search_fields = ['participation_date']
class eventAdmin(admin.ModelAdmin):
inlines = [ParticipationInline,]
Amdouni Mouna 4 Twin 6
StackedInline
class ParticipationInline(admin.StackedInline):
model = Participation
extra = 1
readonly_fields = ('participation_date',)
Inlines can_delete = True
● Partie client:
Views.py
path('events/', include('events.urls')),
]
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'events',
'users',
'bootstrap4',
]
STATIC_URL = 'static/'
events/urls.py views.py
from django.http import
from .views import * HttpResponse
from django.urls import path from django.shortcuts import render
http://127.0.0.1:8000/events/home/
Amdouni Mouna 4 Twin 6
Fonctions def
● Liste
examen1/Templates/events/EventList.html
{% block content %}
<div>
<div class="d-flex m-5 flex-wrap">
{% for e in events %}
<div class="card-body">
<h5 class="card-title">{{e.title}}</h5>
<p class="card-text">{{e.Description}}</p>
<p class="card-text">{{e.nbe_participant}}</p>
</div>
<div class="card-footer">
<small class="text-muted">{{e.evt_date}}</small>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
http://127.0.0.1:8000/events/list/
Amdouni Mouna 4 Twin 6
queryset=Person.objects.all()) ,name="list_events_view"),
path('AjouterEvent/', add_event
,name="add_event"),]
#'list_events_view'
mawjouda fel urls.py w hiya esm
l view mte3 lista
examen1/Templates/events/event_form.html
{% block content %}
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
Amdouni Mouna 4 Twin 6
{{form.as_p}}
<input type="submit" value="Save Data" class="btn btn-primary" />
<input type="reset" value="Cancel" class="btn btn-primary" />
</form>
{% endblock %}
http://localhost:8000/events/AjouterEvent/
Amdouni Mouna 4 Twin 6
#'list_events_view'
mawjouda fel urls.py w hiya esm
l view mte3 lista
examen1/Templates/events/event_form.html
{% block content %}
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Save Data" class="btn btn-primary" />
<input type="reset" value="Cancel" class="btn btn-primary" />
</form>
{% endblock %}
● Classes
● List View
<li>
<a href="{% url 'list_events_view' %}" class="btn btn-success" >EventsViews</a>
afficher <br/>
</li>
liste des views.py events/urls.py
evenements class listEventsView(ListView):
model = Event path('eventListclass',listEvent
template_name = 'events/EventList.html' sView.as_view(),name="list
ListView context_object_name ='events'
def get_queryset(self): _events_view "),
return Event.objects.filter(state=True)
examen1/Templates/events/EventList.html
{% block content %}
<div>
<div class="d-flex m-5 flex-wrap">
{% for e in events %}
<div class="card-body">
<h5 class="card-title">{{e.title}}</h5>
<p class="card-text">{{e.Description}}</p>
<p class="card-text">{{e.nbe_participant}}</p>
</div>
<div class="card-footer">
<small class="text-muted">{{e.evt_date}}</small>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
http://localhost:8000/events/eventListclass
Amdouni Mouna 4 Twin 6
● Ajouter View (le ngeri lee get lee post juste na3tyha l model)
<li><a href="{% url 'add_event2' %}" class="btn btn-success" >Add EventView</a> <br/></li>
examen1/Templates/events/event_form.html
{% block content %}
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Save Data" class="btn btn-primary" />
<input type="reset" value="Cancel" class="btn btn-primary" />
</form>
{% endblock %}
● Details View (le ngeri lee get lee post juste na3tyha l model)
<a href="{% url 'detailEventview' e.id %}" class="btn btn-success">Details</a>
Details events/views.py
event
class detailEventview(DetailView):
model = Event
template_name='events/detail_event_view.html'
b View context_object_name="event"
automatique
urls.py
path('detailEventview/<int:pk>',detailEventview.as_view(),name="detailEventview
ModelForm "),
#' list_events_view' mawjouda fel urls.py w hiya esm l view mte3 lista
examen1/Templates/events/detail_event_view.html
{% extends 'base.html' %}
{% block content %}
<h1> event num {{event.id}}</h1>
http://localhost:8000/events/detailEventview/1
Amdouni Mouna 4 Twin 6
automatique vt_date','organizer']
success_url=reverse_lazy( 'list_events_
exclude=('state',)
# widgets = { view') #spécifier l'URL de redirection après
# 'evt_date': forms.DateInput( la création réussie de l'objet Event
# attrs={
# 'type': 'date',
# 'class': 'form-control date-input', urls.py
ModelForm # 'label': 'Tapez la date de l\'événement', path('updateEventView/<int:pk>',
# }
# ) updateEventView.as_view(),name
#} ="updateEventView"),
evt_date=forms.DateField(
label="Event Date",
widget=forms.DateInput(
attrs={
'type' : 'date', #'list_events_view' mawjouda fel
'class' :'form-control date-input' urls.py w hiya esm l view mte3 lista
}
))
organizer=forms.ModelChoiceField(queryset=Person.
objects.all(),label="Choisir un organizer")
http://localhost:8000/events/updateEventView/1
Amdouni Mouna 4 Twin 6
DeleteView event
<a href="{% url 'deleteEventView' e.id %}" class="btn btn-success">Delete</a>
DeleteEvent views.py
class deleteEventView(DeleteView):
model=Event
context_object_name="event"
b View template_name = 'events/delete_event_view.html'
automatique success_url=reverse_lazy('list_events_view')
urls.py
path('deleteEventView/<int:pk>',deleteEventView.as_view(),name="deleteEve
ntView"),
ModelForm
examen1/Templates/events/delete_event_view.html
{% extends "base.html" %}
{% block content %}
<h1>Delete Event</h1>
<p>Are you sure you want to delete {{ event.title }}?</p>
<form method="post">
{% csrf_token %}
<input type="submit" value="Delete">
<a href="{% url 'list_events_view' %}">Cancel</a>
</form>
{% endblock %}
http://localhost:8000/events/deleteEventView/7
Amdouni Mouna 4 Twin 6
Login /Logout 🙂
users/views.py users/urls.py
from django.shortcuts import render
from django.shortcuts import render
from .forms import LoginForm ,RegisterForm from .views import *
from django.shortcuts import redirect from django.urls import path
from django.contrib.auth import authenticate from django.contrib.auth.views import
,login LogoutView
# Create your views here. urlpatterns = [
def signIn(req): path('login/',signIn , name="login"),
path('register/',signUp, name="register"),
form = LoginForm() path('logout/',LogoutView.as_view(),
if req.method=="GET": name="logout")
return ]
render(req,"users/form.html",{'form':
form})
if req.method =="POST":
username= req.POST['username']
pwd =req.POST['password']
user =
authenticate(req,username=username,pa
ssword=pwd)
if user is not None:
login(request=req,user=user)
return redirect('list_events_view')
else :
return
render(req,"users/form.html",{
"error":"invalid
credentials","form":form })
def signUp(req):
form =RegisterForm()
if req.method=="POST":
form=RegisterForm(req.POST)
print(req.POST)
if form.is_valid():
user=form.save()
login(req,user=user)
return redirect('list_events_view')
return
render(req,"users/form.html",{"form":f
orm})
Amdouni Mouna 4 Twin 6
forms.py Templates/users/form.html
from django import forms
from users.models import Person
from django.contrib.auth.forms import {% extends 'base.html' %}
UserCreationForm {% block content %}
from django.contrib.auth import get_user_model
<form method="POST" action="">
{% csrf_token %}
class LoginForm(forms.ModelForm): {{form.as_p}}
<input type="submit" value="Login"
class Meta: class="btn btn-primary" />
model=Person </form>
fields=['username','password'] {% endblock %}
password
=forms.CharField(label="Password",wid
get=forms.PasswordInput())
class RegisterForm(UserCreationForm):
class Meta:
model= get_user_model()
fields=['cin','username','email','first_nam
e',
'last_name','password1','password2']
def save(self, commit=True):
return
super(RegisterForm,self).save(commit)
@login_required(login_url="login" @login_required
)
def createEventModelForm(req): def createEventModelForm(req):
if req.method=='GET': if req.method=='GET':
form=EventModelForm() form=EventModelForm()
return return
render(req,'events/event_form.html',{'form':form render(req,'events/event_form.html',{'form':form
}) })
if req.method == 'POST': if req.method == 'POST':
form=EventModelForm(req.POST, form=EventModelForm(req.POST,
req.FILES) req.FILES)
if form.is_valid(): if form.is_valid():
Event=form.save(commit=False) Event=form.save(commit=False)
Event.save() Event.save()
return redirect('list_events_view') return redirect('list_events_view')
else: else:
return return
Amdouni Mouna 4 Twin 6
render(req,'events/event_form.html',{'form':form render(req,'events/event_form.html',{'form':form
}) })
rest api
apres la creation soit d’un dossier api soit d’une
application nommée api ajouter les 3 fichiers:
serializer=EventSerializer(instance=event,data
=req.data)
if serializer.is_valid():
serializer.save()
return
Response(serializer.data,status=status.HTTP_2
01_CREATED)
return
Response(serializer.errors,status=status.HTTP
_400_BAD_REQUEST)
@api_view(['GET','DELETE'])
def deleteEvent(req,id=None):
try:
event=Event.objects.get(id=id)
except Event.DoesNotExist:
return Response(status="Event not
found")
event.delete
return Response("Event deleted")