all features OK, cleaned up (flake8) code except migrations files
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
19
LITReview/reviews/migrations/0007_alter_review_ticket.py
Normal file
19
LITReview/reviews/migrations/0007_alter_review_ticket.py
Normal file
@@ -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'),
|
||||
),
|
||||
]
|
||||
17
LITReview/reviews/migrations/0008_remove_ticket_topic.py
Normal file
17
LITReview/reviews/migrations/0008_remove_ticket_topic.py
Normal file
@@ -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',
|
||||
),
|
||||
]
|
||||
@@ -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}'
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<p> Suppression effectuée </p>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,23 +1,50 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load reviews_extras %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="row">
|
||||
<div class="d-flex justify-content-center mt-5">
|
||||
<h2> FLux </h2>
|
||||
<h2> Bienvenue {{ request.user }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{% for ticket in tickets %}
|
||||
{% include 'reviews/ticket_detail.html' %}
|
||||
<div class="col-3 align-self-end">
|
||||
<a href="{% url 'review-ticket' ticket.id %}" type="button" class="btn btn-primary">Créer une critique</a>
|
||||
|
||||
<div class="row d-flex justify-content-center mt-4 mb-3">
|
||||
<div class="col-3 d-flex justify-content-center">
|
||||
<a href="{% url 'ticket-add' %}" type="button" class="btn btn-primary">Demander une critique</a>
|
||||
</div>
|
||||
<div class="col-3 d-flex justify-content-center">
|
||||
<a href="{% url 'review-add' %}" type="button" class="btn btn-primary">Créer une critique</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
{% for post in posts %}
|
||||
{% if post.content_type == 'TICKET' %}
|
||||
<div class="row border border-2 border-secondary-subtle my-3">
|
||||
{% include 'reviews/ticket_detail.html' with ticket=post %}
|
||||
<div class="col-6 d-flex justify-content-end mb-2">
|
||||
{% if not post.review %}
|
||||
<div class="col-4 align-self-end">
|
||||
<a href="{% url 'review-ticket' post.id %}" type="button" class="btn btn-primary">Créer une critique</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-6 align-self-end">
|
||||
<i>{% display_owner post.review.user %} créé une critique, le {{ post.time_created|date:"d M Y"}}</i>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% elif post.content_type == 'REVIEW' %}
|
||||
<div class="row border border-2 border-secondary-subtle my-3">
|
||||
{% include 'reviews/review_detail.html' with review=post %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
{% for ticket in tickets %}
|
||||
{% include 'reviews/ticket_detail.html' %}
|
||||
<div class="col-6 d-flex justify-content-end mb-2">
|
||||
{% if ticket.review is not True %}
|
||||
{% if not ticket.review %}
|
||||
<div class="col-4 align-self-end">
|
||||
<a href="{% url 'review-ticket' ticket.id %}" type="button" class="btn btn-primary">Créer une critique</a>
|
||||
</div>
|
||||
@@ -30,5 +30,4 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -2,45 +2,41 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
|
||||
<div class="row">
|
||||
<div class="d-flex justify-content-center mt-5">
|
||||
<h2> Posts </h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row d-flex justify-content-center mt-4 mb-3">
|
||||
{% for ticket in tickets %}
|
||||
{% include 'reviews/ticket_detail.html' %}
|
||||
|
||||
<div class="col-4 d-flex justify-content-end mb-2">
|
||||
{% if perms.reviews.change_ticket %}
|
||||
<div class="col-3 align-self-end">
|
||||
<a href="{% url 'ticket-update' ticket.id %}" type="button" class="btn btn-primary">Modifier</a>
|
||||
</div>
|
||||
<div class="col-3 align-self-end">
|
||||
<a href="{% url 'ticket-delete' ticket.id %}" type="button" class="btn btn-danger">Supprimer</a>
|
||||
</div>
|
||||
{% for ticket in tickets %}
|
||||
<div class="row border border-2 border-secondary-subtle my-3">
|
||||
{% include 'reviews/ticket_detail.html' %}
|
||||
<div class="col d-flex justify-content-end mb-2">
|
||||
<div class="d-flex align-self-end m-2">
|
||||
<a href="{% url 'ticket-update' ticket.id %}" type="button" class="btn btn-primary">Modifier</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% for review in reviews %}
|
||||
{% include 'reviews/review_detail.html' %}
|
||||
<div class="col d-flex justify-content-end mb-2">
|
||||
{% if perms.reviews.change_ticket %}
|
||||
<div class="d-flex align-self-end m-2">
|
||||
<a href="{% url 'review-update' review.id %}" type="button" class="btn btn-primary">Modifier</a>
|
||||
</div>
|
||||
<div class="d-flex align-self-end m-2">
|
||||
<a href="{% url 'review-delete' review.id %}" type="button" class="btn btn-danger">Supprimer</a>
|
||||
</div>
|
||||
<div class="d-flex align-self-end m-2">
|
||||
<a href="{% url 'ticket-delete' ticket.id %}" type="button" class="btn btn-danger">Supprimer</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{% for review in reviews %}
|
||||
<div class="row border border-2 border-secondary-subtle my-3">
|
||||
{% include 'reviews/review_detail.html' %}
|
||||
<div class="col d-flex justify-content-end mb-2">
|
||||
<div class="d-flex align-self-end m-2">
|
||||
<a href="{% url 'review-update' review.id %}" type="button" class="btn btn-primary">Modifier</a>
|
||||
</div>
|
||||
<div class="d-flex align-self-end m-2">
|
||||
<a href="{% url 'review-delete' review.id %}" type="button" class="btn btn-danger">Supprimer</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
<div class="row border border-2 border-secondary-subtle my-3">
|
||||
{% load reviews_extras %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-8 mb-4">
|
||||
{% 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
|
||||
</div>
|
||||
|
||||
<div class="col-4 d-flex justify-content-end">
|
||||
{{ review.time_created }}
|
||||
</div>
|
||||
|
||||
<span style="font-size: 22px">{{ review.headline }} - {{ review.rating }} ★ </span>
|
||||
<p> {{ review.comment }} </p>
|
||||
<div class="d-flex justify-content-center border border-3 mb-3">
|
||||
{% include 'reviews/ticket_detail.html' with ticket=review.ticket %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row d-flex justify-content-center">
|
||||
<span style="font-size: 22px" class="mb-3">{{ review.headline }} - {{ review.rating|rating_stars }}</span>
|
||||
<p> {{ review.comment }} </p>
|
||||
<div class="col-10 border border-2 border-secondary-subtle mb-3">
|
||||
{% include 'reviews/ticket_detail.html' with ticket=review.ticket %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<form method='post' enctype='multipart/form-data'>
|
||||
{% csrf_token %}
|
||||
{{ review_form.headline }}
|
||||
{% for radio in review_form.rating %}
|
||||
<div class="radio">
|
||||
{{ radio }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</form>
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
<div class="row border border-3 border-secondary-subtle">
|
||||
<p>Vous êtes en train de répondre à </p>
|
||||
<div class="col d-flex justify-content-center mb-2">
|
||||
{% include 'reviews/ticket_detail.html' %}</div>
|
||||
<div class="row border border-2 border-secondary-subtle my-3">
|
||||
{% include 'reviews/ticket_detail.html' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,21 +3,22 @@
|
||||
{% block content %}
|
||||
|
||||
<div class="container">
|
||||
<div class="row mt-4">
|
||||
<div class="row my-4">
|
||||
<div class="d-flex justify-content-center">
|
||||
<h2>Modifier votre critique</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row border border-3">
|
||||
<div class="col-8">
|
||||
<p>Vous êtes en train de poster en réponse à</p>
|
||||
</div>
|
||||
<div class="d-flex justify-content-center">
|
||||
{% include 'reviews/ticket_detail.html' with ticket=review.ticket %}
|
||||
</div>
|
||||
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="col-10 border border-2 border-secondary-subtle mb-3">
|
||||
{% include 'reviews/ticket_detail.html' with ticket=review.ticket %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row border border-3 p-2">
|
||||
<div class="col-3">
|
||||
<p>Critique</p>
|
||||
@@ -35,6 +36,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,12 +1,55 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block nav %}
|
||||
<nav>
|
||||
<a href="{% url 'flux' %}">Flux</a>
|
||||
<a href="{% url 'posts' %}">Posts</a>
|
||||
<a href="{% url 'subscribed' %}">Abonnements</a>
|
||||
<a href="{% url 'logout' %}">Se déconnecter</a>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2> Subscribed </h2>
|
||||
|
||||
<div class="container text-center">
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="d-flex justify-content-center my-5">
|
||||
<h2> Suivre d'autres utilisateurs </h2>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="form-group">
|
||||
{{ user_form }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<button type="submit" class="btn btn-primary">Envoyer</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row d-flex justify-content-end">
|
||||
<div class="d-flex justify-content-center mt-5">
|
||||
<h2> Abonnements </h2>
|
||||
</div>
|
||||
|
||||
{% for user in followed %}
|
||||
<div class="col-6 border border-2 m-1">
|
||||
{{ user.followed_user }}
|
||||
</div>
|
||||
<div class="col-3 m-1">
|
||||
<a href="{% url 'unsubscribe' user.followed_user.id %}" type="button" class="btn btn-primary">Se désabonner</a>
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="d-flex justify-content-center mt-5">
|
||||
<h2> Abonnés </h2>
|
||||
</div>
|
||||
{% for user in following %}
|
||||
<div class="col-6 border border-2 m-1">
|
||||
{{ user.user }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-center align-self-center">
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<p> Êtes vous sûr de vouloir supprimer {{ ticket.title }} ? </p>
|
||||
<button type="submit" class="btn btn-warning">Supprimer</button>
|
||||
</form>
|
||||
|
||||
<div class="container text-center" style="height: 100vh">
|
||||
<div class="row h-100 align-items-center">
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<p> Êtes vous sûr de vouloir supprimer la demande "{{ ticket.title }}" ? </p>
|
||||
<button type="submit" class="btn btn-warning">Supprimer</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<div class="row border border-2 border-secondary-subtle my-3">
|
||||
{% load reviews_extras %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-8 mb-4">
|
||||
{% if request.user == ticket.user %}
|
||||
<strong>vous</strong> avez demandé une critique
|
||||
{% else %}
|
||||
<strong>{{ ticket.user }}</strong> a demandé une critique
|
||||
{% endif %}
|
||||
{% display_owner ticket.user %} publié une demande
|
||||
</div>
|
||||
<div class="col-4 d-flex justify-content-end">
|
||||
{{ ticket.time_created }}
|
||||
</div>
|
||||
<p><strong> {{ ticket.title }} </strong></p>
|
||||
<p> {{ ticket.desc }} </p>
|
||||
<div class="col-3 mb-2">
|
||||
<img src="{{ ticket.image.url }}" class="img" style="width: 200px; height: auto" alt="Couverture de {{ ticket.title }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p><strong> {{ ticket.title }} </strong></p>
|
||||
<p> {{ ticket.desc }} </p>
|
||||
|
||||
<div class="col-3 mb-2">
|
||||
<img src="{{ ticket.image.url }}" class="img" alt="Couverture de {{ ticket.title }}">
|
||||
</div>
|
||||
@@ -1,28 +0,0 @@
|
||||
<div class="row border border-2 border-secondary-subtle my-3">
|
||||
<div class="col-8">
|
||||
{% if request.user == ticket.user %}
|
||||
vous avez demandé une critique
|
||||
{% else %}
|
||||
{{ ticket.user }} a demandé une critique
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-4 d-flex justify-content-end">
|
||||
{{ ticket.time_created }}
|
||||
</div>
|
||||
<p> {{ ticket.title }} </p>
|
||||
<p> {{ ticket.body }} </p>
|
||||
<div class="col-3 mb-2">
|
||||
<img src="{{ ticket.image.url }}" class="img" style="width: 200px; height: auto" alt="Couverture de {{ ticket.title }}">
|
||||
</div>
|
||||
<div class="col-4 d-flex justify-content-end mb-2">
|
||||
{% if request.user == ticket.user %}
|
||||
<div class="col-3 align-self-end">
|
||||
<a href="{% url 'ticket-update' ticket.id %}" type="button" class="btn btn-primary">Modifier</a>
|
||||
</div>
|
||||
<div class="col-3 align-self-end">
|
||||
<a href="{% url 'ticket-delete' ticket.id %}" type="button" class="btn btn-danger">Supprimer</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
14
LITReview/reviews/templates/reviews/unsubscribe.html
Normal file
14
LITReview/reviews/templates/reviews/unsubscribe.html
Normal file
@@ -0,0 +1,14 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="container text-center" style="height: 100vh">
|
||||
<div class="row h-100 align-items-center">
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<p> Êtes vous sûr de vouloir vous désabonner de {{ followed.followed_user }} ? </p>
|
||||
<button type="submit" class="btn btn-warning">Confirmer</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
0
LITReview/reviews/templatetags/__init.py__
Normal file
0
LITReview/reviews/templatetags/__init.py__
Normal file
21
LITReview/reviews/templatetags/reviews_extras.py
Normal file
21
LITReview/reviews/templatetags/reviews_extras.py
Normal file
@@ -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"
|
||||
@@ -1,3 +1,3 @@
|
||||
from django.test import TestCase
|
||||
# from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
||||
@@ -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})
|
||||
|
||||
Reference in New Issue
Block a user