separate library, e-literature and software by using proxy models

This commit is contained in:
Oliver Zander 2025-08-20 12:06:43 +02:00 committed by Tobias Herre
parent 60a5538033
commit 4c458c16d7
5 changed files with 184 additions and 55 deletions

View File

@ -3,8 +3,20 @@ import csv
from django.contrib import admin from django.contrib import admin
from django.http import HttpResponse from django.http import HttpResponse
from .models import Account, Project, HonoraryCertificate, Library, IFG, Travel,\ from .models import (
Email, BusinessCard, List, Literature Account,
Project,
HonoraryCertificate,
Library,
ELiterature,
Software,
IFG,
Travel,
Email,
BusinessCard,
List,
Literature,
)
def export_as_csv(self, request, queryset): def export_as_csv(self, request, queryset):
@ -78,7 +90,8 @@ class HonoraryCertificateAdmin(admin.ModelAdmin):
class Media: class Media:
js = ('dropdown/js/otrs_link.js',) js = ('dropdown/js/otrs_link.js',)
@admin.register(Library)
@admin.register(Library, ELiterature, Software)
class LibraryAdmin(admin.ModelAdmin): class LibraryAdmin(admin.ModelAdmin):
save_as = True save_as = True
search_fields = ('realname', 'service_id', 'granted', 'granted_date') search_fields = ('realname', 'service_id', 'granted', 'granted_date')
@ -86,6 +99,21 @@ class LibraryAdmin(admin.ModelAdmin):
list_display_links = ('realname', 'service_id') list_display_links = ('realname', 'service_id')
date_hierarchy = 'granted_date' date_hierarchy = 'granted_date'
readonly_fields = ['service_id'] readonly_fields = ['service_id']
exclude = ['type']
def get_queryset(self, request):
return super().get_queryset(request).filter(type=self.model.TYPE)
def formfield_for_dbfield(self, db_field, request, **kwargs):
if db_field.name == 'library':
kwargs['label'] = self.model.LIBRARY_LABEL
kwargs['help_text'] = self.model.LIBRARY_HELP_TEXT
elif db_field.name == 'duration':
kwargs['help_text'] = self.model.DURATION_HELP_TEXT
return super().formfield_for_dbfield(db_field, request, **kwargs)
@admin.register(IFG) @admin.register(IFG)
class IFGAdmin(admin.ModelAdmin): class IFGAdmin(admin.ModelAdmin):

View File

@ -1,13 +1,25 @@
from django.conf import settings from django.conf import settings
from django.forms import ModelForm, DateField, ChoiceField, RadioSelect, BooleanField from django.forms import ModelForm, ChoiceField, RadioSelect, BooleanField
from django.contrib.admin.widgets import AdminDateWidget from django.contrib.admin.widgets import AdminDateWidget
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from .models import Project, Volunteer, ConcreteVolunteer, Extern, ConcreteExtern, IFG, Library, TYPE_CHOICES,\ from .models import (
HonoraryCertificate, Travel, Email, Literature, List,\ TYPE_CHOICES,
BusinessCard Project,
ConcreteVolunteer,
ConcreteExtern,
IFG,
Library,
ELiterature,
Software,
HonoraryCertificate,
Travel,
Email,
Literature,
List,
BusinessCard,
)
class FdbForm(ModelForm): class FdbForm(ModelForm):
@ -89,6 +101,7 @@ class TravelForm(FdbForm):
'all': ('css/dateFieldNoNowShortcutInTravels.css',) 'all': ('css/dateFieldNoNowShortcutInTravels.css',)
} }
class LibraryForm(FdbForm): class LibraryForm(FdbForm):
class Meta: class Meta:
@ -96,6 +109,26 @@ class LibraryForm(FdbForm):
fields = ['cost', 'library', 'duration', 'notes', 'survey_mail_send'] fields = ['cost', 'library', 'duration', 'notes', 'survey_mail_send']
exclude = ['intern_notes', 'survey_mail_send', 'mail_state'] exclude = ['intern_notes', 'survey_mail_send', 'mail_state']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['library'].label = self._meta.model.LIBRARY_LABEL
self.fields['library'].help_text = self._meta.model.LIBRARY_HELP_TEXT
self.fields['duration'].help_text = self._meta.model.DURATION_HELP_TEXT
class ELiteratureForm(LibraryForm):
class Meta(LibraryForm.Meta):
model = ELiterature
class SoftwareForm(LibraryForm):
class Meta(LibraryForm.Meta):
model = Software
class HonoraryCertificateForm(FdbForm): class HonoraryCertificateForm(FdbForm):
class Meta: class Meta:

View File

@ -0,0 +1,40 @@
# Generated by Django 5.2.5 on 2025-08-20 10:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('input', '0097_alter_realname_and_username'),
]
operations = [
migrations.CreateModel(
name='ELiterature',
fields=[
],
options={
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('input.library',),
),
migrations.CreateModel(
name='Software',
fields=[
],
options={
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('input.library',),
),
migrations.AlterField(
model_name='library',
name='type',
field=models.CharField(choices=[('BIB', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Zugang_zu_Fachliteratur#Bibliotheksstipendium" target="_blank" rel="noopener">Bibliotheksstipendium</a>'), ('ELIT', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Zugang_zu_Fachliteratur#eLiteraturstipendium" target="_blank" rel="noopener">eLiteraturstipendium</a>'), ('SOFT', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Software-Stipendien" target="_blank" rel="noopener">Softwarestipendium</a>')], default='BIB', max_length=4),
),
]

View File

@ -279,18 +279,44 @@ LIBRARY_TYPE_CHOICES = [(choice, TYPE_CHOICES[choice]) for choice in LIBRARY_TYP
# same model is used for Library, ELitStip and Software! # same model is used for Library, ELitStip and Software!
class Library(Grant): class Library(Grant):
TYPE = TYPE_BIB
LIBRARY_LABEL = 'Bibliothek'
LIBRARY_HELP_TEXT = 'Für welche Bibliothek gilt das Stipendium?'
DURATION_HELP_TEXT = mark_safe('In welchem Zeitraum möchtest du recherchieren oder<br>wie lange ist der Bibliotheksausweis gültig?')
type = models.CharField( type = models.CharField(max_length=4, choices=LIBRARY_TYPE_CHOICES, default=TYPE_BIB)
max_length=4,
choices=LIBRARY_TYPE_CHOICES,
default='BIB',
)
library = models.CharField(max_length=200) library = models.CharField(max_length=200)
duration = models.CharField(max_length=100, verbose_name="Dauer") duration = models.CharField(max_length=100, verbose_name="Dauer")
intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen")
def __str__(self): def __str__(self):
return self.library return self.library
def save(self, **kwargs):
self.type = self.TYPE
return super().save(**kwargs)
class ELiterature(Library):
TYPE = TYPE_ELIT
LIBRARY_LABEL = 'Datenbank/Online-Ressource'
LIBRARY_HELP_TEXT = 'Für welche Datenbank/Online-Ressource gilt das Stipendium?'
DURATION_HELP_TEXT = 'Wie lange gilt der Zugang?'
class Meta:
proxy = True
class Software(Library):
TYPE = TYPE_SOFT
LIBRARY_LABEL = 'Software'
LIBRARY_HELP_TEXT = 'Für welche Software gilt das Stipendium?'
DURATION_HELP_TEXT = 'Wie lange gilt die Lizenz?'
class Meta:
proxy = True
SELFBUY_CHOICES = {'TRUE': mark_safe('Ich möchte das Werk selbst kaufen und per Kostenerstattung bei Wikimedia Deutschland abrechnen.'), SELFBUY_CHOICES = {'TRUE': mark_safe('Ich möchte das Werk selbst kaufen und per Kostenerstattung bei Wikimedia Deutschland abrechnen.'),
'FALSE': mark_safe('Ich möchte, dass Wikimedia Deutschland das Werk für mich kauft'), 'FALSE': mark_safe('Ich möchte, dass Wikimedia Deutschland das Werk für mich kauft'),
@ -394,3 +420,16 @@ class BusinessCard(Extern):
default='', help_text="Bitte gib den Namen und die vollständige Adresse ein, an welche die Visitenkarten geschickt werden sollen.") default='', help_text="Bitte gib den Namen und die vollständige Adresse ein, an welche die Visitenkarten geschickt werden sollen.")
send_data_to_print = models.BooleanField(default=False, verbose_name=mark_safe('Datenweitergabe erlauben'), help_text=mark_safe('Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia<br> Deutschland ausgewählten Dienstleister (z. B. <a href="wir-machen-druck.de">wir-machen-druck.de</a>) zum Zwecke des direkten <br> Versands der Druckerzeugnisse an mich.')) send_data_to_print = models.BooleanField(default=False, verbose_name=mark_safe('Datenweitergabe erlauben'), help_text=mark_safe('Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia<br> Deutschland ausgewählten Dienstleister (z. B. <a href="wir-machen-druck.de">wir-machen-druck.de</a>) zum Zwecke des direkten <br> Versands der Druckerzeugnisse an mich.'))
intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen")
MODELS = {
TYPE_BIB: Library,
TYPE_ELIT: ELiterature,
TYPE_MAIL: Email,
TYPE_IFG: IFG,
TYPE_LIT: Literature,
TYPE_LIST: List,
TYPE_TRAV: Travel,
TYPE_SOFT: Software,
TYPE_VIS: BusinessCard,
}

View File

@ -11,28 +11,37 @@ from django.conf import settings
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from .forms import ProjectForm, ExternForm, LibraryForm, IFGForm, LiteratureForm,\ from .forms import (
HonoraryCertificateForm, InternForm, TravelForm, EmailForm,\ INTERN_CHOICES,
ListForm, BusinessCardForm, INTERN_CHOICES ProjectForm,
from .models import Project, TYPE_CHOICES, Library, Literature, Travel, IFG, BusinessCard, Email, List ExternForm,
LibraryForm,
ELiteratureForm,
SoftwareForm,
IFGForm,
LiteratureForm,
HonoraryCertificateForm,
InternForm,
TravelForm,
EmailForm,
ListForm,
BusinessCardForm,
)
from .models import TYPE_CHOICES, MODELS, TYPE_BIB, TYPE_ELIT, TYPE_SOFT
def auth_deny(choice,pk,auth): LIBRARY_FORMS = {
if choice in ('BIB', 'ELIT', 'SOFT'): TYPE_BIB: LibraryForm,
Library.set_granted(pk,auth) TYPE_ELIT: ELiteratureForm,
elif choice == 'LIT': TYPE_SOFT: SoftwareForm,
Literature.set_granted(pk,auth) }
elif choice == 'IFG':
IFG.set_granted(pk,auth)
elif choice == 'TRAV': def auth_deny(choice, pk, auth):
Travel.set_granted(pk,auth) if choice not in MODELS:
elif choice == 'VIS':
BusinessCard.set_granted(pk,auth)
elif choice == 'MAIL':
Email.set_granted(pk,auth)
elif choice == 'LIST':
List.set_granted(pk,auth)
else:
return HttpResponse(f'ERROR! UNKNOWN CHOICE TYPE! {choice}') return HttpResponse(f'ERROR! UNKNOWN CHOICE TYPE! {choice}')
MODELS[choice].set_granted(pk, auth)
return False return False
@login_required @login_required
@ -138,23 +147,6 @@ class InternView(LoginRequiredMixin, CookieWizardView): # pragma: no cover
return done(self.request) return done(self.request)
# these where used as labels in the second form TYPE_CHOICES is used for the first form and the
# text above the second form. only used for BIB, SOFT, ELIT in the moment
LABEL_CHOICES = {'BIB': mark_safe('Bibliothek'),
'ELIT': mark_safe('Datenbank/Online-Ressource'),
'MAIL': mark_safe('E-Mail-Adresse'),
'IFG': mark_safe('Kostenübernahme IFG-Anfrage'),
'LIT': mark_safe('Literaturstipendium'),
'LIST': mark_safe('Mailingliste'),
'TRAV': mark_safe('Reisekosten'),
'SOFT': mark_safe('Software'),
'VIS': mark_safe('Visitenkarten'),
}
HELP_CHOICES = {'BIB': mark_safe("In welchem Zeitraum möchtest du recherchieren oder<br>wie lange ist der Bibliotheksausweis gültig?"),
'ELIT': "Wie lange gilt der Zugang?",
'SOFT': "Wie lange gilt die Lizenz?",
}
class ExternView(CookieWizardView): class ExternView(CookieWizardView):
'''This View is for Volunteers''' '''This View is for Volunteers'''
@ -177,11 +169,8 @@ class ExternView(CookieWizardView):
if choice == 'IFG': if choice == 'IFG':
form = IFGForm(data) form = IFGForm(data)
form.fields['notes'].help_text = mark_safe("Bitte gib an, wie die gewonnenen Informationen den<br>Wikimedia-Projekten zugute kommen sollen.") form.fields['notes'].help_text = mark_safe("Bitte gib an, wie die gewonnenen Informationen den<br>Wikimedia-Projekten zugute kommen sollen.")
elif choice in ('BIB', 'SOFT', 'ELIT'): elif choice in LIBRARY_FORMS:
form = LibraryForm(data) form = LIBRARY_FORMS[choice](data)
form.fields['library'].label = LABEL_CHOICES[choice]
form.fields['library'].help_text = f"Für welche {LABEL_CHOICES[choice]} gilt das Stipendium?"
form.fields['duration'].help_text = HELP_CHOICES[choice]
elif choice == 'MAIL': elif choice == 'MAIL':
form = EmailForm(data) form = EmailForm(data)
form.fields['domain'].help_text = mark_safe("Mit welcher Domain, bzw. für welches Wikimedia-Projekt,<br>möchtest du eine Mailadresse beantragen?") form.fields['domain'].help_text = mark_safe("Mit welcher Domain, bzw. für welches Wikimedia-Projekt,<br>möchtest du eine Mailadresse beantragen?")