Skip to content

Commit

Permalink
add models, admin, factories, admin and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentporte committed Sep 23, 2024
1 parent cffd1e5 commit 69ebc37
Show file tree
Hide file tree
Showing 5 changed files with 296 additions and 0 deletions.
40 changes: 40 additions & 0 deletions lacommunaute/documentation/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from django.contrib import admin

from lacommunaute.documentation.models import Category, Document, DocumentRating


class DocumentInlines(admin.TabularInline):
model = Document
extra = 0
fields = ("name", "short_description")
readonly_fields = ("name", "short_description")

def has_delete_permission(self, request, obj=None):
return False

def has_add_permission(self, request, obj=None):
return False


@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ("name",)
search_fields = ("name",)
fields = ("name", "short_description", "description", "image")
inlines = [DocumentInlines]


@admin.register(Document)
class DocumentAdmin(admin.ModelAdmin):
list_display = ("name", "category")
list_filter = ("category",)
search_fields = ("name",)
fields = ("name", "short_description", "description", "image")


@admin.register(DocumentRating)
class DocumentRatingAdmin(admin.ModelAdmin):
list_display = ("document", "rating", "created_at")
list_filter = ("document",)
list_display_links = ("rating",)
raw_id_fields = ("document", "user")
39 changes: 39 additions & 0 deletions lacommunaute/documentation/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import factory
from faker import Faker

from lacommunaute.documentation.models import Category, Document


faker = Faker()


class AbstractDocumentationFactory(factory.django.DjangoModelFactory):
name = factory.Faker("name")
description = factory.Faker("sentence", nb_words=100)
short_description = factory.Faker("sentence", nb_words=10)
image = factory.django.ImageField(filename="banner.jpg")


class CategoryFactory(AbstractDocumentationFactory):
class Meta:
model = Category

class Params:
for_snapshot = factory.Trait(
name="Test Category", description="Test description", short_description="Test short description"
)


class DocumentFactory(AbstractDocumentationFactory):
category = factory.SubFactory(CategoryFactory)

class Meta:
model = Document

class Params:
for_snapshot = factory.Trait(
name="Test Document",
description="Test description",
short_description="Test short description",
category=factory.SubFactory(CategoryFactory, for_snapshot=True),
)
143 changes: 143 additions & 0 deletions lacommunaute/documentation/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Generated by Django 5.0.9 on 2024-09-23 15:57

import django.db.models.deletion
import machina.models.fields
import storages.backends.s3
import taggit.managers
from django.conf import settings
from django.db import migrations, models

import lacommunaute.utils.validators


class Migration(migrations.Migration):
initial = True

dependencies = [
("partner", "0004_remove_partner_logo_partner_image_alter_partner_name_and_more"),
("taggit", "0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name="Category",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
("name", models.CharField(max_length=100, verbose_name="Name")),
("slug", models.SlugField(max_length=255, unique=True, verbose_name="Slug")),
(
"description",
machina.models.fields.MarkupTextField(
blank=True, no_rendered_field=True, null=True, verbose_name="Description"
),
),
(
"short_description",
models.CharField(blank=True, max_length=400, null=True, verbose_name="Short Description"),
),
(
"image",
models.ImageField(
storage=storages.backends.s3.S3Storage(bucket_name="private-bucket", file_overwrite=False),
upload_to="",
validators=[lacommunaute.utils.validators.validate_image_size],
),
),
("_description_rendered", models.TextField(blank=True, editable=False, null=True)),
],
options={
"verbose_name": "Catégorie",
"verbose_name_plural": "Catégories",
"ordering": ["created"],
},
),
migrations.CreateModel(
name="Document",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
("name", models.CharField(max_length=100, verbose_name="Name")),
("slug", models.SlugField(max_length=255, unique=True, verbose_name="Slug")),
(
"description",
machina.models.fields.MarkupTextField(
blank=True, no_rendered_field=True, null=True, verbose_name="Description"
),
),
(
"short_description",
models.CharField(blank=True, max_length=400, null=True, verbose_name="Short Description"),
),
(
"image",
models.ImageField(
storage=storages.backends.s3.S3Storage(bucket_name="private-bucket", file_overwrite=False),
upload_to="",
validators=[lacommunaute.utils.validators.validate_image_size],
),
),
(
"certified",
models.BooleanField(default=False, verbose_name="Certifié par la communauté de l'inclusion"),
),
("_description_rendered", models.TextField(blank=True, editable=False, null=True)),
(
"category",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="documents",
to="documentation.category",
),
),
(
"partner",
models.ForeignKey(
blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to="partner.partner"
),
),
(
"tags",
taggit.managers.TaggableManager(
help_text="A comma-separated list of tags.",
through="taggit.TaggedItem",
to="taggit.Tag",
verbose_name="Tags",
),
),
],
options={
"verbose_name": "Document",
"verbose_name_plural": "Documents",
"ordering": ["-created"],
},
),
migrations.CreateModel(
name="DocumentRating",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("created", models.DateTimeField(blank=True, null=True)),
("updated", models.DateTimeField(blank=True, null=True)),
("session_id", models.CharField(max_length=40)),
("rating", models.PositiveSmallIntegerField()),
(
"document",
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="documentation.document"),
),
(
"user",
models.ForeignKey(
blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
],
options={
"verbose_name": "Notation d'un document",
"verbose_name_plural": "Notations des documents",
"ordering": ("-created",),
},
),
]
49 changes: 49 additions & 0 deletions lacommunaute/documentation/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from django.conf import settings
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from taggit.managers import TaggableManager

from lacommunaute.forum_upvote.models import UpVote
from lacommunaute.partner.models import Partner
from lacommunaute.utils.abstract_models import Publication


class Category(Publication):
class Meta:
verbose_name = "Catégorie"
verbose_name_plural = "Catégories"
ordering = ["created"]

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


class Document(Publication):
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="documents")
partner = models.ForeignKey(Partner, on_delete=models.CASCADE, null=True, blank=True)
upvotes = GenericRelation(UpVote, related_query_name="document")
certified = models.BooleanField(default=False, verbose_name="Certifié par la communauté de l'inclusion")
tags = TaggableManager()

class Meta:
verbose_name = "Document"
verbose_name_plural = "Documents"
ordering = ["-created"]

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


# use abstracted DatedModel after ForumRanting migration
class DocumentRating(models.Model):
created = models.DateTimeField(null=True, blank=True)
updated = models.DateTimeField(null=True, blank=True)
session_id = models.CharField(max_length=40)
document = models.ForeignKey(Document, on_delete=models.CASCADE)
rating = models.PositiveSmallIntegerField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)

class Meta:
verbose_name = "Notation d'un document"
verbose_name_plural = "Notations des documents"
ordering = ("-created",)
25 changes: 25 additions & 0 deletions lacommunaute/documentation/tests/tests_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pytest # noqa
from django.db.utils import IntegrityError
from lacommunaute.documentation.factories import CategoryFactory, DocumentFactory


class TestCategory:
def test_slug(self, db):
category = CategoryFactory(for_snapshot=True)
assert category.slug == "test-category"

def test_slug_is_unique(self, db):
CategoryFactory(for_snapshot=True)
with pytest.raises(IntegrityError):
CategoryFactory(for_snapshot=True)


class TestDocument:
def test_slug(self, db):
document = DocumentFactory(for_snapshot=True)
assert document.slug == "test-document"

def test_slug_is_unique(self, db):
DocumentFactory(for_snapshot=True)
with pytest.raises(IntegrityError):
DocumentFactory(for_snapshot=True)

0 comments on commit 69ebc37

Please sign in to comment.