Add category and tag pages

This commit is contained in:
Guillaume Bertholon 2020-11-22 19:01:21 +01:00
parent be99a76829
commit 68dea4002c
16 changed files with 161 additions and 44 deletions

View file

@ -1,4 +1,4 @@
# Generated by Django 3.1.2 on 2020-10-11 15:42 # Generated by Django 3.1.2 on 2020-11-21 18:17
import autoslug.fields import autoslug.fields
from django.db import migrations, models from django.db import migrations, models
@ -18,6 +18,7 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=256, verbose_name='nom')), ('name', models.CharField(max_length=256, verbose_name='nom')),
('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='name', unique=True)),
], ],
options={ options={
'verbose_name': 'catégorie', 'verbose_name': 'catégorie',
@ -28,6 +29,7 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=256, verbose_name='nom')), ('name', models.CharField(max_length=256, verbose_name='nom')),
('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='name', unique=True)),
], ],
), ),
migrations.CreateModel( migrations.CreateModel(
@ -41,7 +43,7 @@ class Migration(migrations.Migration):
('editor', models.CharField(blank=True, max_length=256, verbose_name='éditeur')), ('editor', models.CharField(blank=True, max_length=256, verbose_name='éditeur')),
('game_designer', models.CharField(blank=True, max_length=256, verbose_name='game designer')), ('game_designer', models.CharField(blank=True, max_length=256, verbose_name='game designer')),
('description', models.TextField(blank=True, verbose_name='description')), ('description', models.TextField(blank=True, verbose_name='description')),
('image', models.ImageField(blank=True, upload_to='game_images/', verbose_name='image')), ('image', models.ImageField(blank=True, upload_to='game_img/', verbose_name='image')),
('category', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='inventory.category', verbose_name='catégorie')), ('category', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='inventory.category', verbose_name='catégorie')),
('tags', models.ManyToManyField(blank=True, to='inventory.Tag', verbose_name='tags')), ('tags', models.ManyToManyField(blank=True, to='inventory.Tag', verbose_name='tags')),
], ],

View file

@ -1,18 +0,0 @@
# Generated by Django 3.1.2 on 2020-10-21 19:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='game',
name='image',
field=models.ImageField(blank=True, upload_to='game_img/', verbose_name='image'),
),
]

View file

@ -1,9 +1,11 @@
from django.db import models from django.db import models
from django.urls import reverse
from autoslug import AutoSlugField from autoslug import AutoSlugField
class Category(models.Model): class Category(models.Model):
name = models.CharField(max_length=256, verbose_name="nom") name = models.CharField(max_length=256, verbose_name="nom")
slug = AutoSlugField(populate_from="name", unique=True)
class Meta: class Meta:
verbose_name = "catégorie" verbose_name = "catégorie"
@ -11,13 +13,20 @@ class Category(models.Model):
def __str__(self): def __str__(self):
return self.name return self.name
def get_absolute_url(self):
return reverse("inventory:category", args=(self.slug,))
class Tag(models.Model): class Tag(models.Model):
name = models.CharField(max_length=256, verbose_name="nom") name = models.CharField(max_length=256, verbose_name="nom")
slug = AutoSlugField(populate_from="name", unique=True)
def __str__(self): def __str__(self):
return self.name return self.name
def get_absolute_url(self):
return reverse("inventory:tag", args=(self.slug,))
class Game(models.Model): class Game(models.Model):
title = models.CharField(verbose_name="titre", max_length=256) title = models.CharField(verbose_name="titre", max_length=256)
@ -43,3 +52,6 @@ class Game(models.Model):
def __str__(self): def __str__(self):
return self.title return self.title
def get_absolute_url(self):
return reverse("inventory:game", args=(self.slug,))

View file

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block "content" %}
<h1><i class="fa fa-bookmark" aria-hidden="true"></i> {{ category.name }}</h1>
{% with game_list=category.game_set.all %}
Il y a {{ game_list|length }} jeu{{ game_list|pluralize:"x" }} dans cette catégorie&nbsp;:
<ul>
{% for game in game_list %}
<li><a href="{{ game.get_absolute_url }}">{{ game.title }}</a></li>
{% endfor %}
</ul>
{% endwith %}
{% endblock %}

View file

@ -0,0 +1,12 @@
{% extends "base.html" %}
{% block "content" %}
<h1><i class="fa fa-bookmark" aria-hidden="true"></i> Liste des catégories</h1>
Il y a {{ category_list|length }} catégorie{{ category_list|pluralize }} de jeux&nbsp;:
<ul>
{% for category in category_list %}
<li><a href="{{ category.get_absolute_url }}">{{ category.name }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View file

@ -1,4 +1,5 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load static %}
{% block "content" %} {% block "content" %}
<h1>{{ game.title }}</h1> <h1>{{ game.title }}</h1>
@ -9,21 +10,21 @@
{% endif %} {% endif %}
<div id="details"> <div id="details">
<p><i class="fa fa-fw fa-bookmark"></i> {{ game.category }}</p> <p><i class="fa fa-fw fa-bookmark"></i> <a href="{{ game.category.get_absolute_url }}">{{ game.category }}</a></p>
<hr/> <hr/>
<p><i class="fa fa-fw fa-users" aria-hidden="true"></i> {{ game.player_range }}</p> <p><i class="fa fa-fw fa-users" aria-hidden="true"></i> {{ game.player_range }}</p>
<p><i class="fa fa-fw fa-clock-o" aria-hidden="true"></i> {{ game.duration }} <p><i class="fa fa-fw fa-clock-o" aria-hidden="true"></i> {{ game.duration }}
<hr/> <hr/>
<p><i class="fa fa-fw fa-tags" aria-hidden="true"></i> <p><i class="fa fa-fw fa-tags" aria-hidden="true"></i>
{% if game.tags.count %} {% for tag in game.tags.all %}
{{ game.tags.all|join:", " }} <a href="{{ tag.get_absolute_url }}">{{ tag }}</a>{% if not forloop.last %},{% endif %}
{% else %} {% empty %}
(Aucun tag) (Aucun tag)
{% endif %} {% endfor %}
</p> </p>
<hr/> <hr/>
<p><i class="fa fa-fw fa-pencil" aria-hidden="true"></i> {{ game.game_designer }}</li> <p><i class="fa fa-fw fa-pencil" aria-hidden="true"></i> {{ game.game_designer|default:"(Game designer inconnu)" }}</li>
<p><i class="fa fa-fw fa-cogs" aria-hidden="true"></i> {{ game.editor }}</p> <p><i class="fa fa-fw fa-cogs" aria-hidden="true"></i> {{ game.editor|default:"(Éditeur inconnu)" }}</p>
</div> </div>
</div> </div>

View file

@ -0,0 +1,12 @@
{% extends "base.html" %}
{% block "content" %}
<h1>Liste des jeux</h1>
Il y a {{ game_list|length }} jeu{{ game_list|pluralize:"x" }} en salle jeux&nbsp;:
<ul>
{% for game in game_list %}
<li><a href="{{ game.get_absolute_url }}">{{game.title}}</a></li>
{% endfor %}
</ul>
{% endblock %}

View file

@ -3,10 +3,24 @@
{% block "content" %} {% block "content" %}
<h1>Inventaire du club Jeux</h1> <h1>Inventaire du club Jeux</h1>
Il y a {{ game_list|length }} jeux en salle jeux&nbsp;: <div class="btn_row">
<ul> <a href="{% url "inventory:category_list" %}">
{% for game in game_list %} Liste des catégories
<li><a href="{{ game.get_absolute_url }}">{{game.title}}</a></li> <p class="helptext">
{% endfor %} Chaque jeu est rangé dans une unique catégorie comme en salle Jeux
</ul> </p>
</a>
<a href="{% url "inventory:tag_list" %}">
Liste des tags
<p class="helptext">
Chaque jeu est marqué par tous les tags qui lui correspondent
</p>
</a>
<a href="{% url "inventory:game_list" %}">
Liste alphabétique
<p class="helptext">
La liste complète des jeux de la ludothèque
</p>
</a>
</div>
{% endblock %} {% endblock %}

View file

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block "content" %}
<h1><i class="fa fa-tag" aria-hidden="true"></i> {{ tag.name }}</h1>
{% with game_list=tag.game_set.all %}
Il y a {{ game_list|length }} jeu{{ game_list|pluralize:"x" }} marqué{{ game_list|pluralize }} avec ce tag&nbsp;:
<ul>
{% for game in game_list %}
<li><a href="{{ game.get_absolute_url }}">{{ game.title }}</a></li>
{% endfor %}
</ul>
{% endwith %}
{% endblock %}

View file

@ -0,0 +1,12 @@
{% extends "base.html" %}
{% block "content" %}
<h1><i class="fa fa-tags" aria-hidden="true"></i> Liste des tags</h1>
Il y a {{ tag_list|length }} tag{{ tag_list|pluralize }} dans la ludothèque&nbsp;:
<ul>
{% for tag in tag_list %}
<li><a href="{{ tag.get_absolute_url }}">{{ tag.name }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View file

@ -1,9 +1,22 @@
from django.urls import path from django.urls import path
from .views import InventoryView, GameView from .views import (
InventoryView,
CategoryListView,
CategoryView,
TagListView,
TagView,
GameListView,
GameView,
)
app_name = "inventory" app_name = "inventory"
urlpatterns = [ urlpatterns = [
path("", InventoryView.as_view(), name="inventory"), path("", InventoryView.as_view(), name="inventory"),
path("<slug>/", GameView.as_view(), name="game"), path("category/", CategoryListView.as_view(), name="category_list"),
path("category/<slug>/", CategoryView.as_view(), name="category"),
path("tag/", TagListView.as_view(), name="tag_list"),
path("tag/<slug>/", TagView.as_view(), name="tag"),
path("game/", GameListView.as_view(), name="game_list"),
path("game/<slug>/", GameView.as_view(), name="game"),
] ]

View file

@ -1,12 +1,36 @@
from django.views.generic import ListView, DetailView from django.views.generic import TemplateView, ListView, DetailView
from .models import Game from .models import Category, Tag, Game
class InventoryView(ListView): class InventoryView(TemplateView):
model = Game
template_name = "inventory/inventory.html" template_name = "inventory/inventory.html"
class CategoryListView(ListView):
model = Category
template_name = "inventory/category_list.html"
class CategoryView(DetailView):
model = Category
template_name = "inventory/category.html"
class TagListView(ListView):
model = Tag
template_name = "inventory/tag_list.html"
class TagView(DetailView):
model = Tag
template_name = "inventory/tag.html"
class GameListView(ListView):
model = Game
template_name = "inventory/game_list.html"
class GameView(DetailView): class GameView(DetailView):
model = Game model = Game
template_name = "inventory/game.html" template_name = "inventory/game.html"

View file

@ -248,9 +248,13 @@ iframe {
} }
img { img {
max-width: 50%; width: 50%;
border: solid $indexbar_bg_color_1; border: solid $indexbar_bg_color_1;
border-radius: 10px; border-radius: 10px;
@media (max-width: 500px) {
width: 75%;
}
} }
#details { #details {

View file

@ -396,9 +396,12 @@ iframe {
#game_infos { #game_infos {
flex-direction: column; } } flex-direction: column; } }
#game_infos img { #game_infos img {
max-width: 50%; width: 50%;
border: solid rgba(107, 184, 196, 0.75); border: solid rgba(107, 184, 196, 0.75);
border-radius: 10px; } border-radius: 10px; }
@media (max-width: 500px) {
#game_infos img {
width: 75%; } }
#game_infos #details { #game_infos #details {
flex: 1 0 auto; flex: 1 0 auto;
text-align: left; text-align: left;

View file

@ -1,5 +1,3 @@
{% load static %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="fr"> <html lang="fr">
<head> <head>

View file

@ -4,5 +4,5 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GestioJeux</title> <title>GestioJeux</title>
<link type="text/css" rel="stylesheet" href="{% static "css/style.css" %}" /> <link type="text/css" rel="stylesheet" href="{% static "css/style.css" %}" />
<link rel="shortcut icon" type="image/png" href="/static/img/favicon.png"/> <link rel="shortcut icon" type="image/png" href="{% static "img/favicon.png" %}"/>
<script src="{% static "js/jquery-3.4.1.min.js" %}"></script> <script src="{% static "js/jquery-3.4.1.min.js" %}"></script>