Skip to content

Commit

Permalink
feat(partner): ajout des pages partenaires (#757)
Browse files Browse the repository at this point in the history
## Description

🎸 Afficher des pages d'information sur les partenaires
🎸 Préparer les liens entre les fiches pratiques et les partenaires

## Type de changement

🎢 Nouvelle fonctionnalité (changement non cassant qui ajoute une
fonctionnalité).

### Points d'attention

🦺 ajout `app`, `model`, `detail view` et `list view`
🦺 affichage lien vers la page de mise à jour dans l'admin, si
utilisateur est super_user
🦺 champ `description` est interprété en markdown, champ `logo` est une
image stockée dans le bucket s3


### Captures d'écran (optionnel)

detail view


![image](https://github.com/user-attachments/assets/cc2356aa-0f2f-4160-8161-a9d269403d8e)

list view


![image](https://github.com/user-attachments/assets/881b3f0c-47ec-42a7-9736-4f1728c514b2)

pagination


![image](https://github.com/user-attachments/assets/b91cbe0f-1841-44cd-91d5-693dc1feb427)


lien en pied de page


![image](https://github.com/user-attachments/assets/887d73b9-6a13-4e00-9b74-ee0d9426a291)
  • Loading branch information
vincentporte authored Sep 3, 2024
1 parent 284d50a commit 33fd1c6
Show file tree
Hide file tree
Showing 25 changed files with 617 additions and 0 deletions.
1 change: 1 addition & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"lacommunaute.forum_file",
"lacommunaute.search",
"lacommunaute.surveys",
"lacommunaute.partner",
]

INSTALLED_APPS = DJANGO_APPS + LOCAL_APPS + THIRD_PARTIES_APPS
Expand Down
2 changes: 2 additions & 0 deletions config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from lacommunaute.forum_upvote import urls as forum_upvote_urls
from lacommunaute.inclusion_connect import urls as inclusion_connect_urls
from lacommunaute.pages import urls as pages_urls
from lacommunaute.partner import urls as partner_urls
from lacommunaute.search import urls as search_urls
from lacommunaute.stats import urls as stats_urls
from lacommunaute.surveys import urls as surveys_urls
Expand All @@ -38,6 +39,7 @@
path("", include(forum_moderation_urls)),
path("calendar/", include(event_urls)),
path("surveys/", include(surveys_urls)),
path("partners/", include(partner_urls)),
path("statistiques/", include(stats_urls)),
# machina legacy
path("", include(conversation_urlpatterns_factory.urlpatterns)),
Expand Down
4 changes: 4 additions & 0 deletions lacommunaute/forum/management/commands/populate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from lacommunaute.event.factories import EventFactory
from lacommunaute.forum.factories import CategoryForumFactory, ForumFactory
from lacommunaute.forum_conversation.factories import AnonymousTopicFactory, PostFactory, TopicFactory
from lacommunaute.partner.factories import PartnerFactory
from lacommunaute.users.factories import UserFactory


Expand Down Expand Up @@ -37,6 +38,9 @@ def handle(self, *args, **options):
EventFactory.create_batch(5)
sys.stdout.write("events created\n")

PartnerFactory.create_batch(5, with_logo=True)
sys.stdout.write("partners created\n")

# refresh materialized view
with connection.cursor() as cursor:
cursor.execute("REFRESH MATERIALIZED VIEW search_commonindex")
Expand Down
3 changes: 3 additions & 0 deletions lacommunaute/pages/tests/__snapshots__/test_homepage.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
</li>
</ul>
<ul>
<li>
<a href="/partners/">Nos partenaires</a>
</li>
<li>
<a href="/surveys/dsp/create/">Diagnostic Parcours IAE</a>
</li>
Expand Down
Empty file.
10 changes: 10 additions & 0 deletions lacommunaute/partner/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.contrib import admin

from lacommunaute.partner.models import Partner


@admin.register(Partner)
class PartnerAdmin(admin.ModelAdmin):
list_display = ("name", "url", "created")
search_fields = ("name",)
list_filter = ("created",)
8 changes: 8 additions & 0 deletions lacommunaute/partner/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.apps import AppConfig


class PartenerAppConfig(AppConfig):
label = "partner"
name = "lacommunaute.partner"
verbose_name = "Partner"
verbose_name_plural = "Partners"
28 changes: 28 additions & 0 deletions lacommunaute/partner/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import factory
from faker import Faker

from lacommunaute.partner.models import Partner


faker = Faker()


class PartnerFactory(factory.django.DjangoModelFactory):
class Meta:
model = Partner

name = factory.LazyAttribute(lambda x: faker.company())
short_description = factory.LazyAttribute(lambda x: faker.text(max_nb_chars=200))
description = factory.LazyAttribute(
lambda x: "\n".join([f"### part {i} \n{faker.paragraph(nb_sentences=20)}" for i in range(2)])
)
url = factory.LazyAttribute(lambda x: faker.url())

class Params:
with_logo = factory.Trait(logo=factory.django.ImageField(filename="test.jpg"))
for_snapshot = factory.Trait(
name="Best Partner Ever",
description="### h3 long MD description \n lorem ipsum dolor sit amet, consectetur adipiscing elit.",
short_description="short description for SEO",
url="https://www.best-partner-ever.com",
)
52 changes: 52 additions & 0 deletions lacommunaute/partner/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Generated by Django 5.0.8 on 2024-09-03 11:35

import machina.models.fields
import storages.backends.s3
from django.db import migrations, models

import lacommunaute.utils.validators


class Migration(migrations.Migration):
initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="Partner",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("created", models.DateTimeField(auto_now_add=True, verbose_name="Creation date")),
("updated", models.DateTimeField(auto_now=True, verbose_name="Update date")),
("name", models.CharField(max_length=100, unique=True, verbose_name="Nom")),
("slug", models.SlugField(max_length=255, verbose_name="Slug")),
(
"short_description",
models.CharField(blank=True, max_length=400, null=True, verbose_name="Description courte (SEO)"),
),
(
"description",
machina.models.fields.MarkupTextField(
blank=True, no_rendered_field=True, null=True, verbose_name="Description"
),
),
(
"logo",
models.ImageField(
help_text="1200x600 recommandé",
storage=storages.backends.s3.S3Storage(bucket_name="private-bucket", file_overwrite=False),
upload_to="logos/",
validators=[lacommunaute.utils.validators.validate_image_size],
),
),
("url", models.URLField(blank=True, null=True, verbose_name="Lien vers le site du partenaire")),
("_description_rendered", models.TextField(blank=True, editable=False, null=True)),
],
options={
"verbose_name": "Partner",
"verbose_name_plural": "Partners",
"ordering": ["-created"],
},
),
]
Empty file.
44 changes: 44 additions & 0 deletions lacommunaute/partner/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from django.conf import settings
from django.db import models
from django.urls import reverse
from django.utils.encoding import force_str
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from machina.models.abstract_models import DatedModel
from machina.models.fields import MarkupTextField
from storages.backends.s3boto3 import S3Boto3Storage

from lacommunaute.utils.validators import validate_image_size


class Partner(DatedModel):
name = models.CharField(max_length=100, verbose_name="Nom", unique=True)
slug = models.SlugField(max_length=255, verbose_name="Slug")
short_description = models.CharField(
max_length=400, blank=True, null=True, verbose_name="Description courte (SEO)"
)
description = MarkupTextField(verbose_name="Description", null=True, blank=True)
logo = models.ImageField(
storage=S3Boto3Storage(bucket_name=settings.AWS_STORAGE_BUCKET_NAME, file_overwrite=False),
validators=[validate_image_size],
upload_to="logos/",
help_text="1200x600 recommandé",
)
url = models.URLField(verbose_name="Lien vers le site du partenaire", null=True, blank=True)

objects = models.Manager()

class Meta:
verbose_name = _("Partner")
verbose_name_plural = _("Partners")
ordering = ["-created"]

def __str__(self):
return f"{self.name}"

def save(self, *args, **kwargs):
self.slug = slugify(force_str(self.name), allow_unicode=True)
super().save(*args, **kwargs)

def get_absolute_url(self):
return reverse("partner:detail", kwargs={"slug": self.slug, "pk": self.pk})
Empty file.
180 changes: 180 additions & 0 deletions lacommunaute/partner/tests/__snapshots__/tests_partner_detailview.ambr
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# serializer version: 1
# name: test_partner_detailview[<lambda>-partner_detailview as anonymous][partner_detailview as anonymous]
'''
<main class="s-main" id="main" role="main">





<div class="container">
<nav aria-label="Fil d'ariane" class="c-breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">Retourner vers</li>
<li class="breadcrumb-item">
<a class="matomo-event" data-matomo-action="view" data-matomo-category="engagement" data-matomo-option="partner-list" href="/partners/">Nos partenaires</a>
</li>
</ol>
</nav>
</div>




<section class="s-title-01 mt-lg-5">
<div class="s-title-01__container container">
<div class="s-title-01__row row">
<div class="s-title-01__col col-12">
<div class="d-flex gap-3 align-items-center mb-2">

<img alt="Best Partner Ever" class="img-fluid" src="[img src]" width="200"/>

<h1 class="mb-0">Best Partner Ever</h1>
</div>

<h2 class="mt-3">short description for SEO</h2>
</div>
</div>
</div>
</section>
<section class="s-section">
<div class="s-section__container container">
<div class="s-section__row row">
<div class="col-12">
<article class="textarea_cms_md"><h3>h3 long MD description</h3>

<p>lorem ipsum dolor sit amet, consectetur adipiscing elit.</p></article>

<div class="mt-3">
<a class="has-external-link" href="https://www.best-partner-ever.com" rel="noopener noreferrer" target="_blank">https://www.best-partner-ever.com</a>
</div>

</div>
</div>
</div>
</section>


</main>
'''
# ---
# name: test_partner_detailview[<lambda>-partner_detailview as superuser][partner_detailview as superuser]
'''
<main class="s-main" id="main" role="main">





<div class="container">
<nav aria-label="Fil d'ariane" class="c-breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">Retourner vers</li>
<li class="breadcrumb-item">
<a class="matomo-event" data-matomo-action="view" data-matomo-category="engagement" data-matomo-option="partner-list" href="/partners/">Nos partenaires</a>
</li>
</ol>
</nav>
</div>




<section class="s-title-01 mt-lg-5">
<div class="s-title-01__container container">
<div class="s-title-01__row row">
<div class="s-title-01__col col-12">
<div class="d-flex gap-3 align-items-center mb-2">

<img alt="Best Partner Ever" class="img-fluid" src="[img src]" width="200"/>

<h1 class="mb-0">Best Partner Ever</h1>
</div>

<a href="/admin/partner/partner/[PK of Partner]/change/"><small>Mettre à jour</small></a>

<h2 class="mt-3">short description for SEO</h2>
</div>
</div>
</div>
</section>
<section class="s-section">
<div class="s-section__container container">
<div class="s-section__row row">
<div class="col-12">
<article class="textarea_cms_md"><h3>h3 long MD description</h3>

<p>lorem ipsum dolor sit amet, consectetur adipiscing elit.</p></article>

<div class="mt-3">
<a class="has-external-link" href="https://www.best-partner-ever.com" rel="noopener noreferrer" target="_blank">https://www.best-partner-ever.com</a>
</div>

</div>
</div>
</div>
</section>


</main>
'''
# ---
# name: test_partner_detailview[<lambda>-partner_detailview][partner_detailview]
'''
<main class="s-main" id="main" role="main">





<div class="container">
<nav aria-label="Fil d'ariane" class="c-breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">Retourner vers</li>
<li class="breadcrumb-item">
<a class="matomo-event" data-matomo-action="view" data-matomo-category="engagement" data-matomo-option="partner-list" href="/partners/">Nos partenaires</a>
</li>
</ol>
</nav>
</div>




<section class="s-title-01 mt-lg-5">
<div class="s-title-01__container container">
<div class="s-title-01__row row">
<div class="s-title-01__col col-12">
<div class="d-flex gap-3 align-items-center mb-2">

<img alt="Best Partner Ever" class="img-fluid" src="[img src]" width="200"/>

<h1 class="mb-0">Best Partner Ever</h1>
</div>

<h2 class="mt-3">short description for SEO</h2>
</div>
</div>
</div>
</section>
<section class="s-section">
<div class="s-section__container container">
<div class="s-section__row row">
<div class="col-12">
<article class="textarea_cms_md"><h3>h3 long MD description</h3>

<p>lorem ipsum dolor sit amet, consectetur adipiscing elit.</p></article>

<div class="mt-3">
<a class="has-external-link" href="https://www.best-partner-ever.com" rel="noopener noreferrer" target="_blank">https://www.best-partner-ever.com</a>
</div>

</div>
</div>
</div>
</section>


</main>
'''
# ---
Loading

0 comments on commit 33fd1c6

Please sign in to comment.