diff --git a/LITReview/LITReview/settings.py b/LITReview/LITReview/settings.py index bbdddf1..d0dc2a5 100644 --- a/LITReview/LITReview/settings.py +++ b/LITReview/LITReview/settings.py @@ -20,7 +20,8 @@ BASE_DIR = Path(__file__).resolve().parent.parent # See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-i^f6dau&ze)tzjzf*e#c%+r%sla+-q&e+on(-*xg&t$toyt24y' +SECRET_KEY = \ + 'django-insecure-i^f6dau&ze)tzjzf*e#c%+r%sla+-q&e+on(-*xg&t$toyt24y' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -37,7 +38,7 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'authentication', + 'authentication', 'reviews', ] @@ -89,16 +90,21 @@ DATABASES = { AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + 'NAME': + 'django.contrib.auth.\ + password_validation.UserAttributeSimilarityValidator', }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + 'NAME': 'django.contrib.auth.\ + password_validation.MinimumLengthValidator', }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + 'NAME': 'django.contrib.auth.\ + password_validation.CommonPasswordValidator', }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + 'NAME': 'django.contrib.auth.\ + password_validation.NumericPasswordValidator', }, ] @@ -125,7 +131,7 @@ STATIC_URL = 'static/' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' -LOGIN_REDIRECT_URL = 'home' +LOGIN_REDIRECT_URL = 'flux' LOGIN_URL = 'login' @@ -136,6 +142,3 @@ AUTH_USER_MODEL = 'authentication.User' MEDIA_URL = 'media/uploads/' MEDIA_ROOT = BASE_DIR.joinpath('media/uploads/') - - - diff --git a/LITReview/LITReview/urls.py b/LITReview/LITReview/urls.py index dfaa3f8..69bbb68 100644 --- a/LITReview/LITReview/urls.py +++ b/LITReview/LITReview/urls.py @@ -18,21 +18,17 @@ from django.contrib import admin from django.urls import path from django.conf import settings from django.conf.urls.static import static -from django.contrib.auth.views import LoginView, LogoutView, PasswordChangeView, PasswordChangeDoneView -import authentication.views, reviews.views +from django.contrib.auth.views import LoginView, LogoutView +import authentication.views +import reviews.views urlpatterns = [ path('admin/', admin.site.urls), path('home/', reviews.views.home, name='home'), path('', LoginView.as_view( -# path('', authentication.views.login_page, name='login'), template_name='authentication/login.html', redirect_authenticated_user=True), name='login'), - path('pwd-change/', PasswordChangeView.as_view( - template_name='authentication/pwd_change.html'), name='pwd-change'), - path('pwd-change-done/', PasswordChangeDoneView.as_view( - template_name='authentication/pwd_change_done.html'), name='pwd-change-done'), path('logout/', LogoutView.as_view(next_page='login'), name='logout'), path('register/', authentication.views.register_page, name='register'), path('flux/', reviews.views.flux, name='flux'), @@ -40,14 +36,22 @@ urlpatterns = [ path('subscribed/', reviews.views.subscribed, name='subscribed'), path('ticket/add/', reviews.views.create_ticket, name='ticket-add'), path('review/add/', reviews.views.create_review, name='review-add'), - path('ticket//', reviews.views.ticket, name='ticket-detail'), - path('ticket//update/', reviews.views.update_ticket, name='ticket-update'), - path('ticket//delete/', reviews.views.delete_ticket, name='ticket-delete'), - path('ticket//review/', reviews.views.ticket_review, name='review-ticket'), - path('review//', reviews.views.review, name='review-detail'), - path('review//update/', reviews.views.update_review, name='review-update'), - path('review//delete/', reviews.views.delete_review, name='review-delete'), - path('confirm/', reviews.views.delete_confirm, name='delete-confirm'), + path('ticket//', + reviews.views.ticket, name='ticket-detail'), + path('ticket//update/', + reviews.views.update_ticket, name='ticket-update'), + path('ticket//delete/', + reviews.views.delete_ticket, name='ticket-delete'), + path('ticket//review/', + reviews.views.ticket_review, name='review-ticket'), + path('review//', + reviews.views.review, name='review-detail'), + path('review//update/', + reviews.views.update_review, name='review-update'), + path('review//delete/', + reviews.views.delete_review, name='review-delete'), + path('unsubscribe//', + reviews.views.unsubscribe, name='unsubscribe'), ] if settings.DEBUG: diff --git a/LITReview/authentication/admin.py b/LITReview/authentication/admin.py index 8c38f3f..4185d36 100644 --- a/LITReview/authentication/admin.py +++ b/LITReview/authentication/admin.py @@ -1,3 +1,3 @@ -from django.contrib import admin +# from django.contrib import admin # Register your models here. diff --git a/LITReview/authentication/forms.py b/LITReview/authentication/forms.py index bb5019d..351367d 100644 --- a/LITReview/authentication/forms.py +++ b/LITReview/authentication/forms.py @@ -5,10 +5,12 @@ from django.contrib.auth.forms import UserCreationForm class LoginForm(forms.Form): username = forms.CharField(max_length=63, label='Nom d’utilisateur') - password = forms.CharField(max_length=63, widget=forms.PasswordInput, label='Mot de passe') + password = forms.CharField(max_length=63, + widget=forms.PasswordInput, + label='Mot de passe') + class RegisterForm(UserCreationForm): class Meta(UserCreationForm.Meta): model = get_user_model() fields = ('username',) - diff --git a/LITReview/authentication/models.py b/LITReview/authentication/models.py index 696b770..3d30525 100644 --- a/LITReview/authentication/models.py +++ b/LITReview/authentication/models.py @@ -1,4 +1,3 @@ -from django.db import models from django.contrib.auth.models import AbstractUser diff --git a/LITReview/authentication/templates/authentication/login.html b/LITReview/authentication/templates/authentication/login.html index 724ed81..595bce8 100644 --- a/LITReview/authentication/templates/authentication/login.html +++ b/LITReview/authentication/templates/authentication/login.html @@ -25,11 +25,13 @@ {% csrf_token %}
{{ form.username }} -
+
{{ form.password }}
- +
+ +
diff --git a/LITReview/authentication/templates/authentication/register.html b/LITReview/authentication/templates/authentication/register.html index 8cbd480..03c6002 100644 --- a/LITReview/authentication/templates/authentication/register.html +++ b/LITReview/authentication/templates/authentication/register.html @@ -1,26 +1,30 @@ {% extends 'base.html' %} {% block content %}
-
+

Inscrivez-vous

-
-
+ +
+
{% csrf_token %} {{ form.as_p }} -
-
- - -
-
- Retourner -
+ +
+
+ Retourner +
+
+
+ + +
+
{% endblock %} diff --git a/LITReview/authentication/tests.py b/LITReview/authentication/tests.py index 7ce503c..a79ca8b 100644 --- a/LITReview/authentication/tests.py +++ b/LITReview/authentication/tests.py @@ -1,3 +1,3 @@ -from django.test import TestCase +# from django.test import TestCase # Create your tests here. diff --git a/LITReview/authentication/views.py b/LITReview/authentication/views.py index c3eeceb..cfeeaeb 100644 --- a/LITReview/authentication/views.py +++ b/LITReview/authentication/views.py @@ -1,32 +1,7 @@ from django.shortcuts import render, redirect -from django.contrib.auth import login, logout, authenticate +from django.contrib.auth import login from django.conf import settings -from django import forms -from authentication.forms import LoginForm, RegisterForm - - -def login_page(request): - form = LoginForm() - message = "" - - if request.method == 'POST': - form = LoginForm(request.POST) - if form.is_valid(): - user = authenticate( - username=form.cleaned_data['username'], - password=form.cleaned_data['password'], - ) - if user is not None: - login(request, user) - return redirect('home') - else: - message = "Identifiants invalides" - - print(request.POST) - - return render(request, - 'authentication/login.html', - {'form': form}) +from authentication.forms import RegisterForm def register_page(request): diff --git a/LITReview/media/uploads/VieilHommeMer.jpg b/LITReview/media/uploads/VieilHommeMer.jpg new file mode 100644 index 0000000..195a3bc Binary files /dev/null and b/LITReview/media/uploads/VieilHommeMer.jpg differ diff --git a/LITReview/media/uploads/bergson.jpg b/LITReview/media/uploads/bergson.jpg index f6f1ded..2ef44cc 100644 Binary files a/LITReview/media/uploads/bergson.jpg and b/LITReview/media/uploads/bergson.jpg differ diff --git a/LITReview/media/uploads/crocblanc.jpg b/LITReview/media/uploads/crocblanc.jpg index 31ad68b..7a54222 100644 Binary files a/LITReview/media/uploads/crocblanc.jpg and b/LITReview/media/uploads/crocblanc.jpg differ diff --git a/LITReview/media/uploads/horde_contrevent.jpg b/LITReview/media/uploads/horde_contrevent.jpg new file mode 100644 index 0000000..af88537 Binary files /dev/null and b/LITReview/media/uploads/horde_contrevent.jpg differ diff --git a/LITReview/media/uploads/punch.jpeg b/LITReview/media/uploads/punch.jpeg index 09d8baa..0f743ae 100644 Binary files a/LITReview/media/uploads/punch.jpeg and b/LITReview/media/uploads/punch.jpeg differ diff --git a/LITReview/media/uploads/punch_kX6sdM6.jpeg b/LITReview/media/uploads/punch_kX6sdM6.jpeg new file mode 100644 index 0000000..2b290aa Binary files /dev/null and b/LITReview/media/uploads/punch_kX6sdM6.jpeg differ diff --git a/LITReview/media/uploads/punch_sfEVezr.jpeg b/LITReview/media/uploads/punch_sfEVezr.jpeg new file mode 100644 index 0000000..0f743ae Binary files /dev/null and b/LITReview/media/uploads/punch_sfEVezr.jpeg differ diff --git a/LITReview/reviews/admin.py b/LITReview/reviews/admin.py index bce8588..f4d0a30 100644 --- a/LITReview/reviews/admin.py +++ b/LITReview/reviews/admin.py @@ -1,7 +1,9 @@ from django.contrib import admin +from authentication.models import User from reviews.models import Ticket, Review, UserFollows admin.site.register(Ticket) admin.site.register(Review) admin.site.register(UserFollows) +admin.site.register(User) diff --git a/LITReview/reviews/forms.py b/LITReview/reviews/forms.py index 4f0ac47..cbcdf6e 100644 --- a/LITReview/reviews/forms.py +++ b/LITReview/reviews/forms.py @@ -11,8 +11,11 @@ class TicketForm(forms.ModelForm): class ReviewForm(forms.ModelForm): CHOICES = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5} rating = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES) + class Meta: model = models.Review fields = ['headline', 'rating', 'comment'] +class ToFollowForm(forms.Form): + user = forms.CharField(label="Nom d'utilisateur", max_length=50) diff --git a/LITReview/reviews/migrations/0007_alter_review_ticket.py b/LITReview/reviews/migrations/0007_alter_review_ticket.py new file mode 100644 index 0000000..8d87306 --- /dev/null +++ b/LITReview/reviews/migrations/0007_alter_review_ticket.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2 on 2025-05-02 12:48 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('reviews', '0006_ticket_review_alter_review_ticket'), + ] + + operations = [ + migrations.AlterField( + model_name='review', + name='ticket', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='of_ticket', to='reviews.ticket'), + ), + ] diff --git a/LITReview/reviews/migrations/0008_remove_ticket_topic.py b/LITReview/reviews/migrations/0008_remove_ticket_topic.py new file mode 100644 index 0000000..bfa4aff --- /dev/null +++ b/LITReview/reviews/migrations/0008_remove_ticket_topic.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2 on 2025-05-05 14:10 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('reviews', '0007_alter_review_ticket'), + ] + + operations = [ + migrations.RemoveField( + model_name='ticket', + name='topic', + ), + ] diff --git a/LITReview/reviews/models.py b/LITReview/reviews/models.py index 62ef0ad..1adca80 100644 --- a/LITReview/reviews/models.py +++ b/LITReview/reviews/models.py @@ -7,13 +7,15 @@ from PIL import Image class Ticket(models.Model): # Your Ticket model definition goes here title = models.CharField("Titre", max_length=100) - topic = models.CharField(max_length=100) desc = models.CharField("Description", max_length=8192) user = models.ForeignKey( to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE) image = models.ImageField() time_created = models.DateTimeField(auto_now_add=True) - review = models.ForeignKey(to='reviews.Review', on_delete=models.SET_NULL, related_name='has_review', null=True) + review = models.ForeignKey(to='reviews.Review', + on_delete=models.SET_NULL, + related_name='has_review', + null=True) IMAGE_SIZE = (400, 400) @@ -21,28 +23,39 @@ class Ticket(models.Model): image = Image.open(self.image) image.thumbnail(self.IMAGE_SIZE) image.save(self.image.path) - + def save(self, *args, **kwargs): super().save(*args, **kwargs) self.resize_image() class Review(models.Model): - ticket = models.ForeignKey(to=Ticket, on_delete=models.CASCADE, related_name='of_ticket') + ticket = models.ForeignKey(to=Ticket, + on_delete=models.CASCADE, + related_name='of_ticket', + null=True) rating = models.PositiveSmallIntegerField( # validates that rating must be between 0 and 5 validators=[MinValueValidator(0), MaxValueValidator(5)]) headline = models.CharField("titre", max_length=128) - comment = models.CharField("commentaire", max_length=8192, blank=True) - user = models.ForeignKey( - to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + comment = models.CharField("commentaire", + max_length=8192, + blank=True) + user = models.ForeignKey(to=settings.AUTH_USER_MODEL, + on_delete=models.CASCADE) time_created = models.DateTimeField(auto_now_add=True) class UserFollows(models.Model): # Your UserFollows model definition goes here - user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="following", null=True) - followed_user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="followed", null=True) + user = models.ForeignKey(to=settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name="following", + null=True) + followed_user = models.ForeignKey(to=settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name="followed", + null=True) starting_date = models.DateTimeField(auto_now_add=True) class Meta: @@ -50,3 +63,5 @@ class UserFollows(models.Model): # for unique user-user_followed pairs unique_together = ('user', 'followed_user', ) + def __str__(self): + return f'{self.user} -> {self.followed_user}' diff --git a/LITReview/reviews/templates/reviews/delete_confirm.html b/LITReview/reviews/templates/reviews/delete_confirm.html deleted file mode 100644 index b72601f..0000000 --- a/LITReview/reviews/templates/reviews/delete_confirm.html +++ /dev/null @@ -1,9 +0,0 @@ -{% extends 'base.html' %} - -{% block content %} - -
-

Suppression effectuée

-
- -{% endblock %} diff --git a/LITReview/reviews/templates/reviews/flux.html b/LITReview/reviews/templates/reviews/flux.html index f962588..4ea2071 100644 --- a/LITReview/reviews/templates/reviews/flux.html +++ b/LITReview/reviews/templates/reviews/flux.html @@ -1,23 +1,50 @@ {% extends 'base.html' %} +{% load reviews_extras %} {% block content %}
+
-

FLux

+

Bienvenue {{ request.user }}

-
- {% for ticket in tickets %} - {% include 'reviews/ticket_detail.html' %} -
- Créer une critique + + + +
+ {% for post in posts %} + {% if post.content_type == 'TICKET' %} +
+ {% include 'reviews/ticket_detail.html' with ticket=post %} +
+ {% if not post.review %} + + {% else %} +
+ {% display_owner post.review.user %} créé une critique, le {{ post.time_created|date:"d M Y"}} +
+ {% endif %} +
-
- {% endfor %} -
+ {% elif post.content_type == 'REVIEW' %} +
+ {% include 'reviews/review_detail.html' with review=post %} +
+ {% endif %} + {% endfor %} +
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/LITReview/reviews/templates/reviews/home.html b/LITReview/reviews/templates/reviews/home.html index 10aad2d..0b6e02f 100644 --- a/LITReview/reviews/templates/reviews/home.html +++ b/LITReview/reviews/templates/reviews/home.html @@ -19,7 +19,7 @@ {% for ticket in tickets %} {% include 'reviews/ticket_detail.html' %}
- {% if ticket.review is not True %} + {% if not ticket.review %} @@ -30,5 +30,4 @@
- {% endblock %} diff --git a/LITReview/reviews/templates/reviews/posts.html b/LITReview/reviews/templates/reviews/posts.html index 6a60b64..1825e84 100644 --- a/LITReview/reviews/templates/reviews/posts.html +++ b/LITReview/reviews/templates/reviews/posts.html @@ -2,45 +2,41 @@ {% block content %}
+

Posts

-
- {% for ticket in tickets %} - {% include 'reviews/ticket_detail.html' %} - -
- {% if perms.reviews.change_ticket %} -
- Modifier -
-
- Supprimer -
+ {% for ticket in tickets %} +
+ {% include 'reviews/ticket_detail.html' %} +
+ - {% endif %} -
- {% endfor %} - - - {% for review in reviews %} - {% include 'reviews/review_detail.html' %} -
- {% if perms.reviews.change_ticket %} -
- Modifier -
-
- Supprimer -
+ - {% endif %}
- {% endfor %}
+ {% endfor %} + + {% for review in reviews %} +
+ {% include 'reviews/review_detail.html' %} +
+
+ Modifier +
+
+ Supprimer +
+
+
+ {% endfor %} +
{% endblock %} diff --git a/LITReview/reviews/templates/reviews/review_detail.html b/LITReview/reviews/templates/reviews/review_detail.html index 1e0bdc8..4dbee9d 100644 --- a/LITReview/reviews/templates/reviews/review_detail.html +++ b/LITReview/reviews/templates/reviews/review_detail.html @@ -1,18 +1,19 @@ -
+{% load reviews_extras %} + +
- {% if request.user == review.user %} - vous avez publié une critique - {% else %} - {{ review.user }} a publié une critique - {% endif %} + {% display_owner review.user %} publié une critique
+
{{ review.time_created }}
- - {{ review.headline }} - {{ review.rating }} ★ -

{{ review.comment }}

-
- {% include 'reviews/ticket_detail.html' with ticket=review.ticket %} -
+
+ +
+ {{ review.headline }} - {{ review.rating|rating_stars }} +

{{ review.comment }}

+
+ {% include 'reviews/ticket_detail.html' with ticket=review.ticket %} +
diff --git a/LITReview/reviews/templates/reviews/review_form.html.2 b/LITReview/reviews/templates/reviews/review_form.html.2 deleted file mode 100644 index 980bcfc..0000000 --- a/LITReview/reviews/templates/reviews/review_form.html.2 +++ /dev/null @@ -1,10 +0,0 @@ -
- {% csrf_token %} - {{ review_form.headline }} - {% for radio in review_form.rating %} -
- {{ radio }} -
- {% endfor %} -
- diff --git a/LITReview/reviews/templates/reviews/review_ticket.html b/LITReview/reviews/templates/reviews/review_ticket.html index 78e3cea..46f250f 100644 --- a/LITReview/reviews/templates/reviews/review_ticket.html +++ b/LITReview/reviews/templates/reviews/review_ticket.html @@ -11,7 +11,9 @@

Vous êtes en train de répondre à

- {% include 'reviews/ticket_detail.html' %}
+
+ {% include 'reviews/ticket_detail.html' %} +
diff --git a/LITReview/reviews/templates/reviews/review_update.html b/LITReview/reviews/templates/reviews/review_update.html index aa6674e..7b26f3c 100644 --- a/LITReview/reviews/templates/reviews/review_update.html +++ b/LITReview/reviews/templates/reviews/review_update.html @@ -3,21 +3,22 @@ {% block content %}
-
+

Modifier votre critique

-

Vous êtes en train de poster en réponse à

-
-
- {% include 'reviews/ticket_detail.html' with ticket=review.ticket %} -
+ +
+
+ {% include 'reviews/ticket_detail.html' with ticket=review.ticket %} +
+

Critique

@@ -35,6 +36,7 @@
+
{% endblock %} diff --git a/LITReview/reviews/templates/reviews/subscribed.html b/LITReview/reviews/templates/reviews/subscribed.html index abe6b15..2c682b0 100644 --- a/LITReview/reviews/templates/reviews/subscribed.html +++ b/LITReview/reviews/templates/reviews/subscribed.html @@ -1,12 +1,55 @@ {% extends 'base.html' %} -{% block nav %} - -{% endblock %} + {% block content %} -

Subscribed

+ +
+
+
+

Suivre d'autres utilisateurs

+
+
+
+ {% csrf_token %} +
+ {{ user_form }} +
+
+
+ +
+ +
+
+ + +
+
+

Abonnements

+
+ + {% for user in followed %} +
+ {{ user.followed_user }} +
+ + + {% endfor %} +
+ +
+
+

Abonnés

+
+ {% for user in following %} +
+ {{ user.user }} +
+ {% endfor %} +
+
+ +
+ {% endblock %} diff --git a/LITReview/reviews/templates/reviews/ticket_delete.html b/LITReview/reviews/templates/reviews/ticket_delete.html index 0ee34d5..ac9b247 100644 --- a/LITReview/reviews/templates/reviews/ticket_delete.html +++ b/LITReview/reviews/templates/reviews/ticket_delete.html @@ -1,12 +1,16 @@ {% extends 'base.html' %} {% block content %} -
-
- {% csrf_token %} -

Êtes vous sûr de vouloir supprimer {{ ticket.title }} ?

- -
+ +
+
+
+ {% csrf_token %} +

Êtes vous sûr de vouloir supprimer la demande "{{ ticket.title }}" ?

+ +
+
+
{% endblock %} diff --git a/LITReview/reviews/templates/reviews/ticket_detail.html b/LITReview/reviews/templates/reviews/ticket_detail.html index 42253bb..437f330 100644 --- a/LITReview/reviews/templates/reviews/ticket_detail.html +++ b/LITReview/reviews/templates/reviews/ticket_detail.html @@ -1,17 +1,17 @@ -
+{% load reviews_extras %} + +
- {% if request.user == ticket.user %} - vous avez demandé une critique - {% else %} - {{ ticket.user }} a demandé une critique - {% endif %} + {% display_owner ticket.user %} publié une demande
{{ ticket.time_created }}
-

{{ ticket.title }}

-

{{ ticket.desc }}

-
- Couverture de {{ ticket.title }} -
+
+

{{ ticket.title }}

+

{{ ticket.desc }}

+ +
+ Couverture de {{ ticket.title }} +
\ No newline at end of file diff --git a/LITReview/reviews/templates/reviews/ticket_detail.html.2 b/LITReview/reviews/templates/reviews/ticket_detail.html.2 deleted file mode 100644 index 85bd98f..0000000 --- a/LITReview/reviews/templates/reviews/ticket_detail.html.2 +++ /dev/null @@ -1,28 +0,0 @@ -
-
- {% if request.user == ticket.user %} - vous avez demandé une critique - {% else %} - {{ ticket.user }} a demandé une critique - {% endif %} -
-
- {{ ticket.time_created }} -
-

{{ ticket.title }}

-

{{ ticket.body }}

-
- Couverture de {{ ticket.title }} -
-
- {% if request.user == ticket.user %} -
- Modifier -
-
- Supprimer -
- {% endif %} -
- -
diff --git a/LITReview/reviews/templates/reviews/unsubscribe.html b/LITReview/reviews/templates/reviews/unsubscribe.html new file mode 100644 index 0000000..3d50351 --- /dev/null +++ b/LITReview/reviews/templates/reviews/unsubscribe.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} + +{% block content %} + +
+
+
+ {% csrf_token %} +

Êtes vous sûr de vouloir vous désabonner de {{ followed.followed_user }} ?

+ +
+
+
+{% endblock %} \ No newline at end of file diff --git a/LITReview/reviews/templatetags/__init.py__ b/LITReview/reviews/templatetags/__init.py__ new file mode 100644 index 0000000..e69de29 diff --git a/LITReview/reviews/templatetags/reviews_extras.py b/LITReview/reviews/templatetags/reviews_extras.py new file mode 100644 index 0000000..dd2fa0c --- /dev/null +++ b/LITReview/reviews/templatetags/reviews_extras.py @@ -0,0 +1,21 @@ +from django import template + + +register = template.Library() + + +@register.filter +def rating_stars(rating): + stars = '' + for i in range(rating): + stars += "★" + for i in range(5 - rating): + stars += "☆" + return stars + + +@register.simple_tag(takes_context=True) +def display_owner(context, user): + if user == context['user']: + return "vous avez" + return f"{user.username} a" diff --git a/LITReview/reviews/tests.py b/LITReview/reviews/tests.py index 7ce503c..a79ca8b 100644 --- a/LITReview/reviews/tests.py +++ b/LITReview/reviews/tests.py @@ -1,3 +1,3 @@ -from django.test import TestCase +# from django.test import TestCase # Create your tests here. diff --git a/LITReview/reviews/views.py b/LITReview/reviews/views.py index a254da3..56b8a13 100644 --- a/LITReview/reviews/views.py +++ b/LITReview/reviews/views.py @@ -1,42 +1,55 @@ from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required, permission_required -from reviews.models import Ticket, Review -from reviews.forms import TicketForm, ReviewForm +from django.db.models import CharField, Value +from authentication.models import User +from reviews.models import Ticket, Review, UserFollows +from reviews.forms import TicketForm, ReviewForm, ToFollowForm +from itertools import chain @login_required def home(request): tickets = Ticket.objects.all() - return render(request, 'reviews/home.html', {'tickets': tickets}) + return render(request, + 'reviews/home.html', + {'tickets': tickets}) + @login_required def flux(request): - tickets = Ticket.objects.all() - reviews = Review.objects.all() - context = { - 'tickets': tickets, - 'reviews': reviews, - } - return render(request, 'reviews/flux.html', context) + followed = UserFollows.objects.filter(user=request.user) + users_followed = [] + for userf in followed: + users_followed.append(userf.followed_user) + tickets = Ticket.objects.filter(user__in=users_followed) + tickets = tickets.annotate(content_type=Value('TICKET', CharField())) + reviews = Review.objects.filter(user__in=users_followed) + reviews = reviews.annotate(content_type=Value('REVIEW', CharField())) + posts = sorted( + chain(reviews, tickets), + key=lambda post: post.time_created, + reverse=True) + return render(request, + 'reviews/flux.html', + {'posts': posts}) + @login_required def posts(request): tickets = Ticket.objects.filter(user=request.user) reviews = Review.objects.filter(user=request.user) return render(request, - 'reviews/posts.html', - {'tickets': tickets, 'reviews': reviews}) + 'reviews/posts.html', + {'tickets': tickets, 'reviews': reviews}) -@login_required -def subscribed(request): - return render(request, 'reviews/subscribed.html') @login_required def ticket(request, ticket_id): ticket = Ticket.objects.get(id=ticket_id) return render(request, - 'reviews/ticket.html', - {'ticket': ticket}) + 'reviews/ticket.html', + {'ticket': ticket}) + @login_required def create_ticket(request): @@ -48,10 +61,11 @@ def create_ticket(request): ticket = ticket_form.save(commit=False) ticket.user = request.user ticket.save() - return redirect('home') - return render(request, - 'reviews/ticket_create.html', - context = {'ticket_form': ticket_form, 'tickets': tickets}) + return redirect('flux') + return render(request, + 'reviews/ticket_create.html', + context={'ticket_form': ticket_form, 'tickets': tickets}) + @login_required @permission_required('review.change_ticket', raise_exception=True) @@ -61,34 +75,36 @@ def update_ticket(request, ticket_id): ticket_form = TicketForm(request.POST, instance=ticket) if ticket_form.is_valid(): ticket = ticket_form.save() - return redirect('home') + return redirect('flux') else: ticket_form = TicketForm(instance=ticket) - return render(request, - 'reviews/ticket_update.html', - {'ticket_form': ticket_form}) + return render(request, + 'reviews/ticket_update.html', + {'ticket_form': ticket_form}) + @login_required -@permission_required('review.onwer', raise_exception=True) +@permission_required('review.delete_ticket', raise_exception=True) def delete_ticket(request, ticket_id): ticket = Ticket.objects.get(id=ticket_id) if request.method == 'POST': ticket.delete() - return redirect('home') + return redirect('flux') + + return render(request, + 'reviews/ticket_delete.html', + {'ticket': ticket}) - return render(request, - 'reviews/ticket_delete.html', - {'ticket': ticket}) @login_required def review(request, review_id): review = Review.objects.get(id=review_id) - ticket = review.ticket return render(request, 'reviews/review.html', {'review': review}) + @login_required def create_review(request): ticket_form = TicketForm() @@ -99,23 +115,24 @@ def create_review(request): print(request.POST) if all([ticket_form.is_valid(), review_form.is_valid()]): - ticket = ticket_form.save(commit=False) - print(ticket) - ticket.user = request.user - ticket.save() - review = review_form.save(commit=False) - print(review) - review.user = request.user - review.ticket = ticket - review.save() - return redirect('posts') + ticket = ticket_form.save(commit=False) + review = review_form.save(commit=False) + review.user = ticket.user = request.user + review.save() + ticket.save() + review.ticket = ticket + ticket.review = review + ticket.save() + review.save() + return redirect('posts') context = { 'ticket_form': ticket_form, 'review_form': review_form, } - return render(request, - 'reviews/review_create.html', context) + return render(request, + 'reviews/review_create.html', context) + @login_required def ticket_review(request, ticket_id): @@ -128,14 +145,17 @@ def ticket_review(request, ticket_id): review = review_form.save(commit=False) review.user = request.user review.ticket = ticket + ticket.review = review review.save() + ticket.review = review + ticket.save() return redirect('posts') context = { 'ticket': ticket, 'review_form': review_form, } return render(request, - 'reviews/review_ticket.html', context) + 'reviews/review_ticket.html', context) @login_required @@ -147,16 +167,15 @@ def update_review(request, review_id): print(review_form.is_valid()) if review_form.is_valid(): review = review_form.save() - return redirect('home') + return redirect('posts') else: review_form = ReviewForm(instance=review) - return render(request, 'reviews/review_update.html', {'review_form': review_form, 'review': review}) + @login_required -@permission_required('review.owner', raise_exception=True) def delete_review(request, review_id): review = Review.objects.get(id=review_id) if request.method == 'POST': @@ -166,12 +185,39 @@ def delete_review(request, review_id): 'reviews/review_delete.html', {'review': review}) -def follow_user(request): - pass -def unfollow_user(request): - pass +@login_required +def subscribed(request): + follows = UserFollows() + user_form = ToFollowForm() + following = UserFollows.objects.filter(followed_user=request.user) + if request.method == 'POST': + user_form = ToFollowForm(request.POST) + if user_form.is_valid(): + user = user_form.cleaned_data["user"] + user_followed = User.objects.filter(username=user) + follows.followed_user = user_followed[0] + follows.user = request.user + follows.save() + return redirect('subscribed') + followed = UserFollows.objects.filter(user=request.user) + context = { + 'user_form': user_form, + 'followed': followed, + 'following': following + } + return render(request, + 'reviews/subscribed.html', context) -def delete_confirm(request, truc_id): - render (request, - 'reviews/delete_confirm.html') + +@login_required +def unsubscribe(request, followed_user_id): + followed = UserFollows.objects.get( + user=request.user, + followed_user=followed_user_id) + if request.method == 'POST': + followed.delete() + return redirect('subscribed') + return render(request, + 'reviews/unsubscribe.html', + {'followed': followed}) diff --git a/LITReview/templates/base.html b/LITReview/templates/base.html index ef26385..0bf067c 100644 --- a/LITReview/templates/base.html +++ b/LITReview/templates/base.html @@ -1,29 +1,32 @@ - - - - LITReview - - - - -
-