From 9ffb6b33bb5b7fb612f5a85a27de132cf2996eeb Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Fri, 28 Nov 2025 19:37:10 +0100 Subject: [PATCH] chore(material/*): reformat using ruff (#15) --- jdav_web/material/admin.py | 50 ++++++++++-------- jdav_web/material/apps.py | 4 +- jdav_web/material/materials.json | 2 +- jdav_web/material/models.py | 69 ++++++++++++++----------- jdav_web/material/tests.py | 88 ++++++++++++++++++-------------- 5 files changed, 120 insertions(+), 93 deletions(-) diff --git a/jdav_web/material/admin.py b/jdav_web/material/admin.py index 68f9d69..803ec21 100644 --- a/jdav_web/material/admin.py +++ b/jdav_web/material/admin.py @@ -1,15 +1,15 @@ from django.contrib import admin -from django.utils.translation import gettext_lazy as _ from django.contrib.admin import SimpleListFilter -from django.db import models -from django import forms +from django.utils.translation import gettext_lazy as _ -from .models import MaterialPart, Ownership, MaterialCategory -#from easy_select2 import apply_select2 +from .models import MaterialCategory +from .models import MaterialPart +from .models import Ownership +# from easy_select2 import apply_select2 class MaterialCategoryAdmin(admin.ModelAdmin): - fields = ['name'] + fields = ["name"] # Register your models here. @@ -18,42 +18,50 @@ class OwnershipInline(admin.TabularInline): This shows the ownership selection directly in the MaterialPart edit view """ + model = Ownership extra = 0 - #formfield_overrides = { + # formfield_overrides = { # models.ForeignKey: {'widget': apply_select2(forms.Select)} - #} + # } class NotTooOldFilter(SimpleListFilter): - title = _('Age') - parameter_name = 'age' + title = _("Age") + parameter_name = "age" def lookups(self, request, model_admin): return ( - ('too_old', _('Not too old')), - ('not_too_old', _('Too old')), + ("too_old", _("Not too old")), + ("not_too_old", _("Too old")), ) def queryset(self, request, queryset): - if self.value() == 'too_old': + if self.value() == "too_old": return queryset.filter(pk__in=[x.pk for x in queryset.all() if x.not_too_old()]) - if self.value() == 'not_too_old': + if self.value() == "not_too_old": return queryset.filter(pk__in=[x.pk for x in queryset.all() if not x.not_too_old()]) class MaterialAdmin(admin.ModelAdmin): """Edit view of a MaterialPart""" - list_display = ('name', 'description', 'quantity_real', - 'ownership_overview', 'buy_date', - 'lifetime', 'not_too_old', 'admin_thumbnail') - search_fields = ('name', 'description') + list_display = ( + "name", + "description", + "quantity_real", + "ownership_overview", + "buy_date", + "lifetime", + "not_too_old", + "admin_thumbnail", + ) + search_fields = ("name", "description") inlines = [OwnershipInline] - list_filter = (NotTooOldFilter, 'material_cat', 'ownership__owner') - #formfield_overrides = { + list_filter = (NotTooOldFilter, "material_cat", "ownership__owner") + # formfield_overrides = { # models.ManyToManyField: {'widget': forms.CheckboxSelectMultiple} - #} + # } admin.site.register(MaterialCategory, MaterialCategoryAdmin) diff --git a/jdav_web/material/apps.py b/jdav_web/material/apps.py index c1ffb6e..f2d097f 100644 --- a/jdav_web/material/apps.py +++ b/jdav_web/material/apps.py @@ -3,5 +3,5 @@ from django.utils.translation import gettext_lazy as _ class MaterialConfig(AppConfig): - name = 'material' - verbose_name = _('material') + name = "material" + verbose_name = _("material") diff --git a/jdav_web/material/materials.json b/jdav_web/material/materials.json index da53968..2d91f68 100644 --- a/jdav_web/material/materials.json +++ b/jdav_web/material/materials.json @@ -39,4 +39,4 @@ "quantity": "2" } } -] \ No newline at end of file +] diff --git a/jdav_web/material/models.py b/jdav_web/material/models.py index 3cac241..10baf6f 100644 --- a/jdav_web/material/models.py +++ b/jdav_web/material/models.py @@ -13,14 +13,15 @@ class MaterialCategory(models.Model): """ Describes one kind of material """ - name = models.CharField(max_length=40, verbose_name=_('Name')) + + name = models.CharField(max_length=40, verbose_name=_("Name")) def __str__(self): return self.name class Meta: - verbose_name = _('Material category') - verbose_name_plural = _('Material categories') + verbose_name = _("Material category") + verbose_name_plural = _("Material categories") # Create your models here. @@ -29,14 +30,16 @@ class MaterialPart(models.Model): Represents one part of material, which is owned (and stored) by different members of the association (Ownership) """ - name = models.CharField(_('name'), max_length=30) - description = models.CharField(_('description'), default='', max_length=140) - quantity = models.IntegerField(_('quantity'), default=0) - buy_date = models.DateField(_('purchase date'), editable=True) - lifetime = models.DecimalField(_('lifetime (years)'), decimal_places=0, max_digits=3) - photo = models.ImageField(_('photo'), upload_to='images', blank=True) - material_cat = models.ManyToManyField(MaterialCategory, default=None, - verbose_name=_('Material category')) + + name = models.CharField(_("name"), max_length=30) + description = models.CharField(_("description"), default="", max_length=140) + quantity = models.IntegerField(_("quantity"), default=0) + buy_date = models.DateField(_("purchase date"), editable=True) + lifetime = models.DecimalField(_("lifetime (years)"), decimal_places=0, max_digits=3) + photo = models.ImageField(_("photo"), upload_to="images", blank=True) + material_cat = models.ManyToManyField( + MaterialCategory, default=None, verbose_name=_("Material category") + ) def __str__(self): """String representation""" @@ -44,53 +47,59 @@ class MaterialPart(models.Model): def quantity_real(self): real = sum([o.count for o in Ownership.objects.filter(material__id=self.pk)]) - return str(real) + '/' + str(self.quantity) + return str(real) + "/" + str(self.quantity) - quantity_real.admin_order_field = 'quantity' - quantity_real.short_description = _('Quantity') + quantity_real.admin_order_field = "quantity" + quantity_real.short_description = _("Quantity") def admin_thumbnail(self): if self.photo: - return format_html(''.format(self.photo.url)) + return format_html( + ''.format( + self.photo.url + ) + ) else: - return format_html('kein Bild') - admin_thumbnail.short_description = _('Thumbnail') + return format_html("kein Bild") + + admin_thumbnail.short_description = _("Thumbnail") def ownership_overview(self): - summary = '' + summary = "" for owner in self.ownership_set.all(): - summary += '

{}: {}

'.format(str(owner.owner), owner.count) + summary += "

{}: {}

".format(str(owner.owner), owner.count) return format_html(summary) - ownership_overview.short_description = _('Owners') + + ownership_overview.short_description = _("Owners") def not_too_old(self): """Returns wether the part should be replaced cause of age""" - buy_time = timezone.make_aware(datetime.combine(self.buy_date, - datetime.min.time())) + buy_time = timezone.make_aware(datetime.combine(self.buy_date, datetime.min.time())) return yearsago(self.lifetime) < buy_time - not_too_old.admin_order_field = 'buy_date' + not_too_old.admin_order_field = "buy_date" not_too_old.boolean = True - not_too_old.short_description = _('Not too old?') + not_too_old.short_description = _("Not too old?") class Meta: - verbose_name = _('material part') - verbose_name_plural = _('material parts') + verbose_name = _("material part") + verbose_name_plural = _("material parts") class Ownership(models.Model): """Represents the connection between a MaterialPart and a Member""" + material = models.ForeignKey(MaterialPart, on_delete=models.CASCADE) - owner = models.ForeignKey('members.Member', verbose_name=_('owner'), on_delete=models.CASCADE) - count = models.IntegerField(_('count'), default=1) + owner = models.ForeignKey("members.Member", verbose_name=_("owner"), on_delete=models.CASCADE) + count = models.IntegerField(_("count"), default=1) def __str__(self): """String representation""" return str(self.owner) class Meta: - verbose_name = _('ownership') - verbose_name_plural = _('ownerships') + verbose_name = _("ownership") + verbose_name_plural = _("ownerships") def yearsago(years, from_date=None): diff --git a/jdav_web/material/tests.py b/jdav_web/material/tests.py index c736ce6..3511e12 100644 --- a/jdav_web/material/tests.py +++ b/jdav_web/material/tests.py @@ -1,11 +1,20 @@ -from django.test import TestCase, RequestFactory -from django.utils import timezone -from datetime import date, datetime +from datetime import date +from datetime import datetime from decimal import Decimal from unittest.mock import Mock -from material.models import MaterialCategory, MaterialPart, Ownership, yearsago -from material.admin import NotTooOldFilter, MaterialAdmin -from members.models import Member, MALE, FEMALE, DIVERSE + +from django.test import RequestFactory +from django.test import TestCase +from django.utils import timezone +from material.admin import MaterialAdmin +from material.admin import NotTooOldFilter +from material.models import MaterialCategory +from material.models import MaterialPart +from material.models import Ownership +from material.models import yearsago +from members.models import FEMALE +from members.models import MALE +from members.models import Member class MaterialCategoryTestCase(TestCase): @@ -19,8 +28,8 @@ class MaterialCategoryTestCase(TestCase): def test_verbose_names(self): """Test verbose names are set correctly""" meta = MaterialCategory._meta - self.assertTrue(hasattr(meta, 'verbose_name')) - self.assertTrue(hasattr(meta, 'verbose_name_plural')) + self.assertTrue(hasattr(meta, "verbose_name")) + self.assertTrue(hasattr(meta, "verbose_name_plural")) class MaterialPartTestCase(TestCase): @@ -31,7 +40,7 @@ class MaterialPartTestCase(TestCase): description="60m dynamic climbing rope", quantity=5, buy_date=date(2020, 1, 15), - lifetime=Decimal('8') + lifetime=Decimal("8"), ) self.material_part.material_cat.add(self.category) @@ -40,7 +49,7 @@ class MaterialPartTestCase(TestCase): lastname="Doe", birth_date=date(1990, 1, 1), email="john@example.com", - gender=MALE + gender=MALE, ) def test_str(self): @@ -54,27 +63,27 @@ class MaterialPartTestCase(TestCase): def test_quantity_real_with_ownership(self): """Test quantity_real with ownership records""" - Ownership.objects.create( - material=self.material_part, - owner=self.member, - count=3 - ) - Ownership.objects.create( - material=self.material_part, - owner=self.member, - count=1 - ) + Ownership.objects.create(material=self.material_part, owner=self.member, count=3) + Ownership.objects.create(material=self.material_part, owner=self.member, count=1) result = self.material_part.quantity_real() self.assertEqual(result, "4/5") def test_verbose_names(self): """Test field verbose names""" # Just test that verbose names exist, since they might be translated - field_names = ['name', 'description', 'quantity', 'buy_date', 'lifetime', 'photo', 'material_cat'] + field_names = [ + "name", + "description", + "quantity", + "buy_date", + "lifetime", + "photo", + "material_cat", + ] for field_name in field_names: field = self.material_part._meta.get_field(field_name) - self.assertTrue(hasattr(field, 'verbose_name')) + self.assertTrue(hasattr(field, "verbose_name")) self.assertIsNotNone(field.verbose_name) def test_admin_thumbnail_with_photo(self): @@ -104,7 +113,7 @@ class MaterialPartTestCase(TestCase): # Set a buy_date that makes the material old old_date = date(2000, 1, 1) self.material_part.buy_date = old_date - self.material_part.lifetime = Decimal('5') + self.material_part.lifetime = Decimal("5") result = self.material_part.not_too_old() self.assertFalse(result) @@ -117,7 +126,7 @@ class OwnershipTestCase(TestCase): description="Lightweight aluminum carabiners", quantity=10, buy_date=date(2021, 6, 1), - lifetime=Decimal('10') + lifetime=Decimal("10"), ) self.member = Member.objects.create( @@ -125,13 +134,11 @@ class OwnershipTestCase(TestCase): lastname="Smith", birth_date=date(1985, 3, 15), email="alice@example.com", - gender=FEMALE + gender=FEMALE, ) self.ownership = Ownership.objects.create( - material=self.material_part, - owner=self.member, - count=6 + material=self.material_part, owner=self.member, count=6 ) def test_ownership_creation(self): @@ -183,8 +190,11 @@ class NotTooOldFilterTestCase(TestCase): # Create test data self.member = Member.objects.create( - prename="Test", lastname="User", birth_date=date(1990, 1, 1), - email="test@example.com", gender=MALE + prename="Test", + lastname="User", + birth_date=date(1990, 1, 1), + email="test@example.com", + gender=MALE, ) # Create old material (should be too old) @@ -193,7 +203,7 @@ class NotTooOldFilterTestCase(TestCase): description="Old material", quantity=1, buy_date=date(2000, 1, 1), # Very old - lifetime=Decimal('5') + lifetime=Decimal("5"), ) # Create new material (should not be too old) @@ -202,21 +212,21 @@ class NotTooOldFilterTestCase(TestCase): description="New material", quantity=1, buy_date=date.today(), # Today - lifetime=Decimal('10') + lifetime=Decimal("10"), ) def test_not_too_old_filter_lookups(self): """Test NotTooOldFilter lookups method""" - request = self.factory.get('/') + request = self.factory.get("/") lookups = self.filter.lookups(request, None) self.assertEqual(len(lookups), 2) - self.assertEqual(lookups[0][0], 'too_old') - self.assertEqual(lookups[1][0], 'not_too_old') + self.assertEqual(lookups[0][0], "too_old") + self.assertEqual(lookups[1][0], "not_too_old") def test_not_too_old_filter_queryset_too_old(self): """Test NotTooOldFilter queryset method with 'too_old' value""" - request = self.factory.get('/?age=too_old') - self.filter.used_parameters = {'age': 'too_old'} + request = self.factory.get("/?age=too_old") + self.filter.used_parameters = {"age": "too_old"} queryset = MaterialPart.objects.all() filtered = self.filter.queryset(request, queryset) @@ -227,8 +237,8 @@ class NotTooOldFilterTestCase(TestCase): def test_not_too_old_filter_queryset_not_too_old(self): """Test NotTooOldFilter queryset method with 'not_too_old' value""" - request = self.factory.get('/?age=not_too_old') - self.filter.used_parameters = {'age': 'not_too_old'} + request = self.factory.get("/?age=not_too_old") + self.filter.used_parameters = {"age": "not_too_old"} queryset = MaterialPart.objects.all() filtered = self.filter.queryset(request, queryset)