mirror of
https://github.com/ae-utbm/sith.git
synced 2026-03-28 14:29:43 +00:00
Compare commits
5 Commits
fix_pagina
...
club-list
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd26b279c1 | ||
|
|
7a69b3441e | ||
|
|
36edcf19d7 | ||
|
|
af59ebc896 | ||
|
|
f6830ebd9b |
17
club/api.py
17
club/api.py
@@ -6,9 +6,10 @@ from ninja_extra.pagination import PageNumberPaginationExtra
|
|||||||
from ninja_extra.schemas import PaginatedResponseSchema
|
from ninja_extra.schemas import PaginatedResponseSchema
|
||||||
|
|
||||||
from api.auth import ApiKeyAuth
|
from api.auth import ApiKeyAuth
|
||||||
from api.permissions import CanAccessLookup, CanView, HasPerm
|
from api.permissions import CanView, HasPerm
|
||||||
from club.models import Club, Membership
|
from club.models import Club, Membership
|
||||||
from club.schemas import (
|
from club.schemas import (
|
||||||
|
ClubProfileSchema,
|
||||||
ClubSchema,
|
ClubSchema,
|
||||||
ClubSearchFilterSchema,
|
ClubSearchFilterSchema,
|
||||||
SimpleClubSchema,
|
SimpleClubSchema,
|
||||||
@@ -22,13 +23,21 @@ class ClubController(ControllerBase):
|
|||||||
@route.get(
|
@route.get(
|
||||||
"/search",
|
"/search",
|
||||||
response=PaginatedResponseSchema[SimpleClubSchema],
|
response=PaginatedResponseSchema[SimpleClubSchema],
|
||||||
auth=[ApiKeyAuth(), SessionAuth()],
|
|
||||||
permissions=[CanAccessLookup],
|
|
||||||
url_name="search_club",
|
url_name="search_club",
|
||||||
)
|
)
|
||||||
@paginate(PageNumberPaginationExtra, page_size=50)
|
@paginate(PageNumberPaginationExtra, page_size=50)
|
||||||
def search_club(self, filters: Query[ClubSearchFilterSchema]):
|
def search_club(self, filters: Query[ClubSearchFilterSchema]):
|
||||||
return filters.filter(Club.objects.all())
|
return filters.filter(Club.objects.order_by("name")).values()
|
||||||
|
|
||||||
|
@route.get(
|
||||||
|
"/search-profile",
|
||||||
|
response=PaginatedResponseSchema[ClubProfileSchema],
|
||||||
|
url_name="search_club_profile",
|
||||||
|
)
|
||||||
|
@paginate(PageNumberPaginationExtra, page_size=50)
|
||||||
|
def search_club_profile(self, filters: Query[ClubSearchFilterSchema]):
|
||||||
|
"""Same as /api/club/search, but with more returned data"""
|
||||||
|
return filters.filter(Club.objects.order_by("name"))
|
||||||
|
|
||||||
@route.get(
|
@route.get(
|
||||||
"/{int:club_id}",
|
"/{int:club_id}",
|
||||||
|
|||||||
@@ -315,3 +315,22 @@ class JoinClubForm(ClubMemberForm):
|
|||||||
_("You are already a member of this club"), code="invalid"
|
_("You are already a member of this club"), code="invalid"
|
||||||
)
|
)
|
||||||
return super().clean()
|
return super().clean()
|
||||||
|
|
||||||
|
|
||||||
|
class ClubSearchForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Club
|
||||||
|
fields = ["name"]
|
||||||
|
widgets = {"name": forms.SearchInput(attrs={"autocomplete": "off"})}
|
||||||
|
|
||||||
|
club_status = forms.NullBooleanField(
|
||||||
|
label=_("Club status"),
|
||||||
|
widget=forms.RadioSelect(
|
||||||
|
choices=[(True, _("Active")), (False, _("Inactive")), ("", _("All clubs"))],
|
||||||
|
),
|
||||||
|
initial=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.fields["name"].required = False
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class ClubProfileSchema(ModelSchema):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Club
|
model = Club
|
||||||
fields = ["id", "name", "logo"]
|
fields = ["id", "name", "logo", "is_active", "short_description"]
|
||||||
|
|
||||||
url: str
|
url: str
|
||||||
|
|
||||||
|
|||||||
47
club/static/club/list.scss
Normal file
47
club/static/club/list.scss
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#club-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2em;
|
||||||
|
padding: 2em;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
display: block;
|
||||||
|
background-color: unset;
|
||||||
|
|
||||||
|
.club-image {
|
||||||
|
float: left;
|
||||||
|
margin-right: 2rem;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
border-radius: 10%;
|
||||||
|
background-color: rgba(173, 173, 173, 0.2);
|
||||||
|
|
||||||
|
@media screen and (max-width: 500px) {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i.club-image {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: block;
|
||||||
|
text-align: justify;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-right: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
{% extends "core/base.jinja" %}
|
{% extends "core/base.jinja" %}
|
||||||
|
{% from "core/macros.jinja" import paginate_jinja with context %}
|
||||||
|
|
||||||
{% block title -%}
|
{% block title -%}
|
||||||
{% trans %}Club list{% endtrans %}
|
{% trans %}Club list{% endtrans %}
|
||||||
@@ -8,45 +9,50 @@
|
|||||||
{% trans %}The list of all clubs existing at UTBM.{% endtrans %}
|
{% trans %}The list of all clubs existing at UTBM.{% endtrans %}
|
||||||
{%- endblock %}
|
{%- endblock %}
|
||||||
|
|
||||||
{% macro display_club(club) -%}
|
{% block additional_css %}
|
||||||
|
<link rel="stylesheet" href="{{ static("club/list.scss") }}">
|
||||||
{% if club.is_active or user.is_root %}
|
{% endblock %}
|
||||||
|
|
||||||
<li><a href="{{ url('club:club_view', club_id=club.id) }}">{{ club.name }}</a>
|
|
||||||
|
|
||||||
{% if not club.is_active %}
|
|
||||||
({% trans %}inactive{% endtrans %})
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if club.president %} - <a href="{{ url('core:user_profile', user_id=club.president.user.id) }}">{{ club.president.user }}</a>{% endif %}
|
|
||||||
{% if club.short_description %}<p>{{ club.short_description|markdown }}</p>{% endif %}
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{%- if club.children.all()|length != 0 %}
|
|
||||||
<ul>
|
|
||||||
{%- for c in club.children.order_by('name').prefetch_related("children") %}
|
|
||||||
{{ display_club(c) }}
|
|
||||||
{%- endfor %}
|
|
||||||
</ul>
|
|
||||||
{%- endif -%}
|
|
||||||
</li>
|
|
||||||
{%- endmacro %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if user.is_root %}
|
<main>
|
||||||
<p><a href="{{ url('club:club_new') }}">{% trans %}New club{% endtrans %}</a></p>
|
<h3>{% trans %}Filters{% endtrans %}</h3>
|
||||||
{% endif %}
|
<form id="club-list-filters" method="GET">
|
||||||
{% if club_list %}
|
<div class="row gap-4x">
|
||||||
|
{{ form }}
|
||||||
|
</div>
|
||||||
|
<input type="submit" class="btn btn-blue margin-bottom" value="{% trans %}Search{% endtrans %}">
|
||||||
|
</form>
|
||||||
<h3>{% trans %}Club list{% endtrans %}</h3>
|
<h3>{% trans %}Club list{% endtrans %}</h3>
|
||||||
<ul>
|
{% if user.has_perm("club.add_club") %}
|
||||||
{%- for club in club_list %}
|
<br>
|
||||||
{{ display_club(club) }}
|
<a href="{{ url('club:club_new') }}" class="btn btn-blue">
|
||||||
{%- endfor %}
|
<i class="fa fa-plus"></i> {% trans %}New club{% endtrans %}
|
||||||
</ul>
|
</a>
|
||||||
{% else %}
|
|
||||||
{% trans %}There is no club in this website.{% endtrans %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<section class="aria-busy-grow" id="club-list">
|
||||||
|
{% for club in object_list %}
|
||||||
|
<div class="card">
|
||||||
|
{% set club_url = club.get_absolute_url() %}
|
||||||
|
<a href="{{ club_url }}">
|
||||||
|
{% if club.logo %}
|
||||||
|
<img class="club-image" src="{{ club.logo.url }}" alt="logo {{ club.name }}">
|
||||||
|
{% else %}
|
||||||
|
<i class="fa-regular fa-image fa-4x club-image"></i>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
<div class="content">
|
||||||
|
<a href="{{ club_url }}">
|
||||||
|
<h4>
|
||||||
|
{{ club.name }} {% if not club.is_active %}({% trans %}inactive{% endtrans %}){% endif %}
|
||||||
|
</h4>
|
||||||
|
</a>
|
||||||
|
{{ club.short_description|markdown }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</section>
|
||||||
|
{{ paginate_jinja(page_obj, paginator) }}
|
||||||
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from django.test import Client
|
||||||
|
from django.urls import reverse
|
||||||
from django.utils.timezone import localdate
|
from django.utils.timezone import localdate
|
||||||
from model_bakery import baker
|
from model_bakery import baker
|
||||||
from model_bakery.recipe import Recipe
|
from model_bakery.recipe import Recipe
|
||||||
|
|
||||||
from club.models import Club, Membership
|
from club.models import Club, Membership
|
||||||
from core.baker_recipes import subscriber_user
|
from core.baker_recipes import subscriber_user
|
||||||
|
from core.models import User
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@@ -25,3 +28,10 @@ def test_club_queryset_having_board_member():
|
|||||||
|
|
||||||
club_ids = Club.objects.having_board_member(user).values_list("id", flat=True)
|
club_ids = Club.objects.having_board_member(user).values_list("id", flat=True)
|
||||||
assert set(club_ids) == {clubs[1].id, clubs[2].id}
|
assert set(club_ids) == {clubs[1].id, clubs[2].id}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_club_list(client: Client):
|
||||||
|
client.force_login(baker.make(User))
|
||||||
|
res = client.get(reverse("club:club_list"))
|
||||||
|
assert res.status_code == 200
|
||||||
|
|||||||
@@ -59,6 +59,14 @@ class TestClubSearch(TestCase):
|
|||||||
ids = {d["id"] for d in response.json()["results"]}
|
ids = {d["id"] for d in response.json()["results"]}
|
||||||
assert ids == {c.id for c in [self.clubs[0], self.clubs[1], self.clubs[3]]}
|
assert ids == {c.id for c in [self.clubs[0], self.clubs[1], self.clubs[3]]}
|
||||||
|
|
||||||
|
def test_club_search_profile(self):
|
||||||
|
self.client.force_login(self.user)
|
||||||
|
url = reverse("api:search_club_profile")
|
||||||
|
response = self.client.get(url, {"search": "AE"})
|
||||||
|
assert response.status_code == 200
|
||||||
|
ids = {d["id"] for d in response.json()["results"]}
|
||||||
|
assert ids == {c.id for c in [self.clubs[0], self.clubs[1], self.clubs[3]]}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
class TestFetchClub:
|
class TestFetchClub:
|
||||||
|
|||||||
@@ -44,13 +44,19 @@ from django.utils.translation import gettext
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.views.generic import DetailView, ListView, View
|
from django.views.generic import DetailView, ListView, View
|
||||||
from django.views.generic.detail import SingleObjectMixin
|
from django.views.generic.detail import SingleObjectMixin
|
||||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
from django.views.generic.edit import (
|
||||||
|
CreateView,
|
||||||
|
DeleteView,
|
||||||
|
FormMixin,
|
||||||
|
UpdateView,
|
||||||
|
)
|
||||||
|
|
||||||
from club.forms import (
|
from club.forms import (
|
||||||
ClubAddMemberForm,
|
ClubAddMemberForm,
|
||||||
ClubAdminEditForm,
|
ClubAdminEditForm,
|
||||||
ClubEditForm,
|
ClubEditForm,
|
||||||
ClubOldMemberForm,
|
ClubOldMemberForm,
|
||||||
|
ClubSearchForm,
|
||||||
JoinClubForm,
|
JoinClubForm,
|
||||||
MailingForm,
|
MailingForm,
|
||||||
SellingsForm,
|
SellingsForm,
|
||||||
@@ -180,15 +186,41 @@ class ClubTabsMixin(TabedViewMixin):
|
|||||||
return tab_list
|
return tab_list
|
||||||
|
|
||||||
|
|
||||||
class ClubListView(ListView):
|
class ClubListView(FormMixin, ListView):
|
||||||
"""List the Clubs."""
|
"""List the clubs of the AE, with a form to perform basic search.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
This view is fully public, because we want to advertise as much as possible
|
||||||
|
the cultural life of the AE.
|
||||||
|
In accordance with that matter, searching and listing the clubs is done
|
||||||
|
entirely server-side (no AlpineJS involved) ;
|
||||||
|
this is done this way in order to be sure the page is the most accessible
|
||||||
|
and SEO-friendly possible, even if it makes the UX slightly less smooth.
|
||||||
|
"""
|
||||||
|
|
||||||
model = Club
|
|
||||||
template_name = "club/club_list.jinja"
|
template_name = "club/club_list.jinja"
|
||||||
queryset = (
|
form_class = ClubSearchForm
|
||||||
Club.objects.filter(parent=None).order_by("name").prefetch_related("children")
|
queryset = Club.objects.order_by("name")
|
||||||
)
|
paginate_by = 20
|
||||||
context_object_name = "club_list"
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
res = super().get_form_kwargs()
|
||||||
|
if self.request.GET:
|
||||||
|
res |= {"data": self.request.GET, "initial": self.request.GET}
|
||||||
|
return res
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
form: ClubSearchForm = self.get_form()
|
||||||
|
qs = self.queryset
|
||||||
|
if not form.is_bound:
|
||||||
|
return qs
|
||||||
|
if not form.is_valid():
|
||||||
|
return qs.none()
|
||||||
|
if name := form.cleaned_data.get("name"):
|
||||||
|
qs = qs.filter(name__icontains=name)
|
||||||
|
if (is_active := form.cleaned_data.get("club_status")) is not None:
|
||||||
|
qs = qs.filter(is_active=is_active)
|
||||||
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class ClubView(ClubTabsMixin, DetailView):
|
class ClubView(ClubTabsMixin, DetailView):
|
||||||
|
|||||||
@@ -5,9 +5,8 @@
|
|||||||
<details name="navbar" class="menu">
|
<details name="navbar" class="menu">
|
||||||
<summary class="head">{% trans %}Associations & Clubs{% endtrans %}</summary>
|
<summary class="head">{% trans %}Associations & Clubs{% endtrans %}</summary>
|
||||||
<ul class="content">
|
<ul class="content">
|
||||||
<li><a href="{{ url('core:page', page_name='ae') }}">{% trans %}AE{% endtrans %}</a></li>
|
<li><a href="{{ url("core:page", page_name="ae") }}">{% trans %}AE{% endtrans %}</a></li>
|
||||||
<li><a href="{{ url('core:page', page_name='clubs') }}">{% trans %}AE's clubs{% endtrans %}</a></li>
|
<li><a href="{{ url("club:club_list") }}">{% trans %}AE's clubs{% endtrans %}</a></li>
|
||||||
<li><a href="{{ url('core:page', page_name='utbm-associations') }}">{% trans %}Others UTBM's Associations{% endtrans %}</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details name="navbar" class="menu">
|
<details name="navbar" class="menu">
|
||||||
|
|||||||
@@ -124,12 +124,15 @@
|
|||||||
This must be coupled with a view that handles pagination
|
This must be coupled with a view that handles pagination
|
||||||
with the Django Paginator object.
|
with the Django Paginator object.
|
||||||
|
|
||||||
Warning:
|
|
||||||
You must include this macro `with context` as it uses the `querystring` macro
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
current_page (django.core.paginator.Page): the current page object
|
current_page (django.core.paginator.Page): the current page object
|
||||||
paginator (django.core.paginator.Paginator): the paginator object
|
paginator (django.core.paginator.Paginator): the paginator object
|
||||||
|
|
||||||
|
Warnings:
|
||||||
|
This macro must be imported with context :
|
||||||
|
```jinja
|
||||||
|
{% from "core/macros.jinja" import paginate_jinja with context %}
|
||||||
|
```
|
||||||
#}
|
#}
|
||||||
{{ paginate_server_side(current_page, paginator, False) }}
|
{{ paginate_server_side(current_page, paginator, False) }}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
@@ -142,12 +145,15 @@
|
|||||||
|
|
||||||
The replaced fragment will be #content so make sure you are calling this macro inside your content block.
|
The replaced fragment will be #content so make sure you are calling this macro inside your content block.
|
||||||
|
|
||||||
Warning:
|
|
||||||
You must include this macro `with context` as it uses the `querystring` macro
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
current_page (django.core.paginator.Page): the current page object
|
current_page (django.core.paginator.Page): the current page object
|
||||||
paginator (django.core.paginator.Paginator): the paginator object
|
paginator (django.core.paginator.Paginator): the paginator object
|
||||||
|
|
||||||
|
Warnings:
|
||||||
|
This macro must be imported with context :
|
||||||
|
```jinja
|
||||||
|
{% from "core/macros.jinja" import paginate_htmx with context %}
|
||||||
|
```
|
||||||
#}
|
#}
|
||||||
{{ paginate_server_side(current_page, paginator, True) }}
|
{{ paginate_server_side(current_page, paginator, True) }}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
@@ -254,5 +260,14 @@
|
|||||||
|
|
||||||
|
|
||||||
{% macro querystring() %}
|
{% macro querystring() %}
|
||||||
{{- urlencode(dict(dict(request.GET.lists()) | items | list + kwargs | items | list), doseq=True) -}}
|
{%- for key, values in request.GET.lists() -%}
|
||||||
|
{%- if key not in kwargs -%}
|
||||||
|
{%- for value in values -%}
|
||||||
|
{{ key }}={{ value }}&
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- for key, value in kwargs.items() -%}
|
||||||
|
{{ key }}={{ value }}&
|
||||||
|
{%- endfor -%}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
{% extends "core/base.jinja" %}
|
{% extends "core/base.jinja" %}
|
||||||
{% from 'core/macros.jinja' import user_profile_link %}
|
{% from 'core/macros.jinja' import user_profile_link, paginate_jinja with context %}
|
||||||
{% from 'core/macros.jinja' import paginate_jinja with context %}
|
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans %}Cash register summary list{% endtrans %}
|
{% trans %}Cash register summary list{% endtrans %}
|
||||||
|
|||||||
@@ -44,9 +44,7 @@
|
|||||||
|
|
||||||
<p><a class="ib button" href="{{ url('forum:new_message', topic_id=topic.id) }}">{% trans %}Reply{% endtrans %}</a></p>
|
<p><a class="ib button" href="{{ url('forum:new_message', topic_id=topic.id) }}">{% trans %}Reply{% endtrans %}</a></p>
|
||||||
|
|
||||||
{% if is_paginated %}
|
|
||||||
{{ paginate_jinja(msgs, msgs.paginator) }}
|
{{ paginate_jinja(msgs, msgs.paginator) }}
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -310,16 +310,36 @@ msgid "The list of all clubs existing at UTBM."
|
|||||||
msgstr "La liste de tous les clubs existants à l'UTBM"
|
msgstr "La liste de tous les clubs existants à l'UTBM"
|
||||||
|
|
||||||
#: club/templates/club/club_list.jinja
|
#: club/templates/club/club_list.jinja
|
||||||
msgid "inactive"
|
msgid "Filters"
|
||||||
msgstr "inactif"
|
msgstr "Filtres"
|
||||||
|
|
||||||
|
#: club/templates/club/club_list.jinja
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Nom"
|
||||||
|
|
||||||
|
#: club/templates/club/club_list.jinja
|
||||||
|
msgid "Club state"
|
||||||
|
msgstr "Etat du club"
|
||||||
|
|
||||||
|
#: club/templates/club/club_list.jinja
|
||||||
|
msgid "Active"
|
||||||
|
msgstr "Actif"
|
||||||
|
|
||||||
|
#: club/templates/club/club_list.jinja
|
||||||
|
msgid "Inactive"
|
||||||
|
msgstr "Inactif"
|
||||||
|
|
||||||
|
#: club/templates/club/club_list.jinja
|
||||||
|
msgid "All clubs"
|
||||||
|
msgstr "Tous les clubs"
|
||||||
|
|
||||||
#: club/templates/club/club_list.jinja core/templates/core/user_tools.jinja
|
#: club/templates/club/club_list.jinja core/templates/core/user_tools.jinja
|
||||||
msgid "New club"
|
msgid "New club"
|
||||||
msgstr "Nouveau club"
|
msgstr "Nouveau club"
|
||||||
|
|
||||||
#: club/templates/club/club_list.jinja
|
#: club/templates/club/club_list.jinja
|
||||||
msgid "There is no club in this website."
|
msgid "inactive"
|
||||||
msgstr "Il n'y a pas de club dans ce site web."
|
msgstr "inactif"
|
||||||
|
|
||||||
#: club/templates/club/club_members.jinja
|
#: club/templates/club/club_members.jinja
|
||||||
msgid "Club members"
|
msgid "Club members"
|
||||||
@@ -1881,10 +1901,6 @@ msgstr "L'AE"
|
|||||||
msgid "AE's clubs"
|
msgid "AE's clubs"
|
||||||
msgstr "Les clubs de L'AE"
|
msgstr "Les clubs de L'AE"
|
||||||
|
|
||||||
#: core/templates/core/base/navbar.jinja
|
|
||||||
msgid "Others UTBM's Associations"
|
|
||||||
msgstr "Les autres associations de l'UTBM"
|
|
||||||
|
|
||||||
#: core/templates/core/base/navbar.jinja
|
#: core/templates/core/base/navbar.jinja
|
||||||
msgid "Big event"
|
msgid "Big event"
|
||||||
msgstr "Grandes Activités"
|
msgstr "Grandes Activités"
|
||||||
|
|||||||
@@ -28,7 +28,5 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
{% if is_paginated %}
|
|
||||||
{{ paginate_jinja(page_obj, paginator) }}
|
{{ paginate_jinja(page_obj, paginator) }}
|
||||||
{% endif %}
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
@@ -190,7 +190,6 @@ TEMPLATES = [
|
|||||||
"get_sith": "com.views.sith",
|
"get_sith": "com.views.sith",
|
||||||
"get_language": "django.utils.translation.get_language",
|
"get_language": "django.utils.translation.get_language",
|
||||||
"timedelta": "datetime.timedelta",
|
"timedelta": "datetime.timedelta",
|
||||||
"urlencode": "urllib.parse.urlencode",
|
|
||||||
},
|
},
|
||||||
"bytecode_cache": {
|
"bytecode_cache": {
|
||||||
"name": "default",
|
"name": "default",
|
||||||
|
|||||||
Reference in New Issue
Block a user