feat: Add history tracking
This commit is contained in:
@@ -41,7 +41,8 @@ dependencies = [
|
|||||||
"django-super-deduper",
|
"django-super-deduper",
|
||||||
"django-allauth[mfa]",
|
"django-allauth[mfa]",
|
||||||
"django_debug_toolbar",
|
"django_debug_toolbar",
|
||||||
"django-admin-extra-buttons"
|
"django-admin-extra-buttons",
|
||||||
|
"django-simple-history"
|
||||||
]
|
]
|
||||||
|
|
||||||
dynamic = ["version", "readme"]
|
dynamic = ["version", "readme"]
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from django.urls import reverse
|
|||||||
from django.utils.http import urlencode
|
from django.utils.http import urlencode
|
||||||
|
|
||||||
from admin_extra_buttons.api import ExtraButtonsMixin, button, link
|
from admin_extra_buttons.api import ExtraButtonsMixin, button, link
|
||||||
|
from simple_history.admin import SimpleHistoryAdmin
|
||||||
|
|
||||||
from .models import Language, Text, ReportComment, ReportAdoptionNotice, Log, Timestamp, SearchSubscription, \
|
from .models import Language, Text, ReportComment, ReportAdoptionNotice, Log, Timestamp, SearchSubscription, \
|
||||||
SpeciesSpecificURL, ImportantLocation, SocialMediaPost
|
SpeciesSpecificURL, ImportantLocation, SocialMediaPost
|
||||||
@@ -50,7 +51,7 @@ class AdoptionNoticeAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
# Re-register UserAdmin
|
# Re-register UserAdmin
|
||||||
@admin.register(User)
|
@admin.register(User)
|
||||||
class UserAdmin(admin.ModelAdmin):
|
class UserAdmin(SimpleHistoryAdmin):
|
||||||
search_fields = ("usernamname__icontains", "first_name__icontains", "last_name__icontains", "email__icontains")
|
search_fields = ("usernamname__icontains", "first_name__icontains", "last_name__icontains", "email__icontains")
|
||||||
list_display = ("username", "email", "trust_level", "is_active", "view_adoption_notices")
|
list_display = ("username", "email", "trust_level", "is_active", "view_adoption_notices")
|
||||||
list_filter = ("is_active", "trust_level",)
|
list_filter = ("is_active", "trust_level",)
|
||||||
@@ -78,7 +79,7 @@ def _reported_content_link(obj):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(ReportComment)
|
@admin.register(ReportComment)
|
||||||
class ReportCommentAdmin(admin.ModelAdmin):
|
class ReportCommentAdmin(SimpleHistoryAdmin):
|
||||||
list_display = ["user_comment", "reported_content_link"]
|
list_display = ["user_comment", "reported_content_link"]
|
||||||
date_hierarchy = "created_at"
|
date_hierarchy = "created_at"
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ class ReportCommentAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(ReportAdoptionNotice)
|
@admin.register(ReportAdoptionNotice)
|
||||||
class ReportAdoptionNoticeAdmin(admin.ModelAdmin):
|
class ReportAdoptionNoticeAdmin(SimpleHistoryAdmin):
|
||||||
list_display = ["user_comment", "reported_content_link"]
|
list_display = ["user_comment", "reported_content_link"]
|
||||||
date_hierarchy = "created_at"
|
date_hierarchy = "created_at"
|
||||||
|
|
||||||
@@ -104,7 +105,7 @@ class SpeciesSpecificURLInline(admin.StackedInline):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(RescueOrganization)
|
@admin.register(RescueOrganization)
|
||||||
class RescueOrganizationAdmin(admin.ModelAdmin):
|
class RescueOrganizationAdmin(SimpleHistoryAdmin):
|
||||||
search_fields = ("name", "description", "internal_comment", "location_string", "location__city")
|
search_fields = ("name", "description", "internal_comment", "location_string", "location__city")
|
||||||
list_display = ("name", "trusted", "allows_using_materials", "website")
|
list_display = ("name", "trusted", "allows_using_materials", "website")
|
||||||
list_filter = ("allows_using_materials", "trusted", ("external_source_identifier", EmptyFieldListFilter))
|
list_filter = ("allows_using_materials", "trusted", ("external_source_identifier", EmptyFieldListFilter))
|
||||||
@@ -115,12 +116,12 @@ class RescueOrganizationAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(Text)
|
@admin.register(Text)
|
||||||
class TextAdmin(admin.ModelAdmin):
|
class TextAdmin(SimpleHistoryAdmin):
|
||||||
search_fields = ("title__icontains", "text_code__icontains",)
|
search_fields = ("title__icontains", "text_code__icontains",)
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Comment)
|
@admin.register(Comment)
|
||||||
class CommentAdmin(admin.ModelAdmin):
|
class CommentAdmin(SimpleHistoryAdmin):
|
||||||
list_filter = ("user",)
|
list_filter = ("user",)
|
||||||
|
|
||||||
|
|
||||||
@@ -130,7 +131,7 @@ class BaseNotificationAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(SearchSubscription)
|
@admin.register(SearchSubscription)
|
||||||
class SearchSubscriptionAdmin(admin.ModelAdmin):
|
class SearchSubscriptionAdmin(SimpleHistoryAdmin):
|
||||||
list_filter = ("owner",)
|
list_filter = ("owner",)
|
||||||
|
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ class IsImportantListFilter(admin.SimpleListFilter):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(Location)
|
@admin.register(Location)
|
||||||
class LocationAdmin(admin.ModelAdmin):
|
class LocationAdmin(SimpleHistoryAdmin):
|
||||||
search_fields = ("name__icontains", "city__icontains")
|
search_fields = ("name__icontains", "city__icontains")
|
||||||
list_filter = [IsImportantListFilter]
|
list_filter = [IsImportantListFilter]
|
||||||
inlines = [
|
inlines = [
|
||||||
@@ -167,7 +168,7 @@ class LocationAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
|
|
||||||
@admin.register(SocialMediaPost)
|
@admin.register(SocialMediaPost)
|
||||||
class SocialMediaPostAdmin(admin.ModelAdmin):
|
class SocialMediaPostAdmin(SimpleHistoryAdmin):
|
||||||
list_filter = ("platform",)
|
list_filter = ("platform",)
|
||||||
|
|
||||||
|
|
||||||
@@ -193,12 +194,13 @@ class LogAdmin(ExtraButtonsMixin, admin.ModelAdmin):
|
|||||||
def invisible(self, button):
|
def invisible(self, button):
|
||||||
button.visible = False
|
button.visible = False
|
||||||
|
|
||||||
admin.site.register(Animal)
|
|
||||||
|
admin.site.register(Animal, SimpleHistoryAdmin)
|
||||||
admin.site.register(Species)
|
admin.site.register(Species)
|
||||||
admin.site.register(Rule)
|
admin.site.register(Rule, SimpleHistoryAdmin)
|
||||||
admin.site.register(Image)
|
admin.site.register(Image)
|
||||||
admin.site.register(ModerationAction)
|
admin.site.register(ModerationAction, SimpleHistoryAdmin)
|
||||||
admin.site.register(Language)
|
admin.site.register(Language)
|
||||||
admin.site.register(Announcement)
|
admin.site.register(Announcement, SimpleHistoryAdmin)
|
||||||
admin.site.register(Subscriptions)
|
admin.site.register(Subscriptions, SimpleHistoryAdmin)
|
||||||
admin.site.register(Timestamp)
|
admin.site.register(Timestamp)
|
||||||
|
|||||||
@@ -0,0 +1,367 @@
|
|||||||
|
# Generated by Django 5.2.8 on 2025-11-16 17:37
|
||||||
|
|
||||||
|
import django.contrib.auth.validators
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
import simple_history.models
|
||||||
|
import uuid
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('fellchensammlung', '0070_user_mod_notes_alter_user_reason_for_signup'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalAdoptionNotice',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('created_at', models.DateField(default=django.utils.timezone.now, verbose_name='Erstellt am')),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('last_checked', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Zuletzt überprüft am')),
|
||||||
|
('searching_since', models.DateField(verbose_name='Sucht nach einem Zuhause seit')),
|
||||||
|
('name', models.CharField(max_length=200, verbose_name='Titel der Vermittlung')),
|
||||||
|
('description', models.TextField(blank=True, null=True, verbose_name='Beschreibung')),
|
||||||
|
('further_information', models.URLField(blank=True, help_text='Verlinke hier die Quelle der Vermittlung (z.B. die Website des Tierheims)', null=True, verbose_name='Link zu mehr Informationen')),
|
||||||
|
('group_only', models.BooleanField(default=False, verbose_name='Ausschließlich Gruppenadoption')),
|
||||||
|
('location_string', models.CharField(max_length=200, verbose_name='Ortsangabe')),
|
||||||
|
('adoption_notice_status', models.TextField(choices=[('active_searching', 'Searching'), ('active_interested', 'Interested'), ('awaiting_action_waiting_for_review', 'Waiting for review'), ('awaiting_action_needs_additional_info', 'Needs additional info'), ('awaiting_action_unchecked', 'Unchecked'), ('closed_successful_with_notfellchen', 'Successful (with Notfellchen)'), ('closed_successful_without_notfellchen', 'Successful (without Notfellchen)'), ('closed_animal_died', 'Animal died'), ('closed_for_other_adoption_notice', 'Closed for other adoption notice'), ('closed_not_open_for_adoption_anymore', 'Not open for adoption anymore'), ('closed_link_to_more_info_not_reachable', 'Der Link zu weiteren Informationen ist nicht mehr erreichbar.'), ('closed_other', 'Other (closed)'), ('disabled_against_the_rules', 'Against the rules'), ('disabled_other', 'Other (disabled)')], max_length=64, verbose_name='Status')),
|
||||||
|
('adoption_process', models.TextField(blank=True, choices=[('contact_person_in_an', 'Kontaktiere die Person im Vermittlungstext')], max_length=64, null=True, verbose_name='Adoptionsprozess')),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('location', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.location')),
|
||||||
|
('organization', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.rescueorganization', verbose_name='Organisation')),
|
||||||
|
('owner', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Creator')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Vermittlung',
|
||||||
|
'verbose_name_plural': 'historical Vermittlungen',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalAnimal',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('date_of_birth', models.DateField(verbose_name='Geburtsdatum')),
|
||||||
|
('name', models.CharField(max_length=200, verbose_name='Name')),
|
||||||
|
('description', models.TextField(blank=True, null=True, verbose_name='Beschreibung')),
|
||||||
|
('sex', models.CharField(choices=[('F', 'Weiblich'), ('M', 'Männlich'), ('M_N', 'Männlich, kastriert'), ('F_N', 'Weiblich, kastriert'), ('I', 'Intergeschlechtlich')], max_length=20, verbose_name='Geschlecht')),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('created_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('adoption_notice', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.adoptionnotice')),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('owner', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('species', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.species', verbose_name='Tierart')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Tier',
|
||||||
|
'verbose_name_plural': 'historical Tiere',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalAnnouncement',
|
||||||
|
fields=[
|
||||||
|
('text_ptr', models.ForeignKey(auto_created=True, blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, parent_link=True, related_name='+', to='fellchensammlung.text')),
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('title', models.CharField(max_length=100, verbose_name='Titel')),
|
||||||
|
('content', models.TextField(verbose_name='Inhalt')),
|
||||||
|
('text_code', models.CharField(blank=True, max_length=24, verbose_name='Text code')),
|
||||||
|
('logged_in_only', models.BooleanField(default=False)),
|
||||||
|
('created_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('publish_start_time', models.DateTimeField(verbose_name='Veröffentlichungszeitpunkt')),
|
||||||
|
('publish_end_time', models.DateTimeField(verbose_name='Veröffentlichungsende')),
|
||||||
|
('type', models.CharField(choices=[('important', 'important'), ('warning', 'warning'), ('info', 'info')], default='info', max_length=100)),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('language', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.language', verbose_name='Sprache')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Banner',
|
||||||
|
'verbose_name_plural': 'historical Banner',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalComment',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('created_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('text', models.TextField(verbose_name='Inhalt')),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('adoption_notice', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.adoptionnotice', verbose_name='Vermittlung')),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('reply_to', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.comment', verbose_name='Antwort auf')),
|
||||||
|
('user', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Nutzer*in')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Kommentar',
|
||||||
|
'verbose_name_plural': 'historical Kommentare',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalModerationAction',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('action', models.CharField(choices=[('user_banned', 'User was banned'), ('content_deleted', 'Content was deleted'), ('comment', 'Comment was added'), ('other_action_taken', 'Other action was taken'), ('no_action_taken', 'No action was taken')], max_length=30)),
|
||||||
|
('created_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('public_comment', models.TextField(blank=True)),
|
||||||
|
('private_comment', models.TextField(blank=True)),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('report', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.report')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Moderationsaktion',
|
||||||
|
'verbose_name_plural': 'historical Moderationsaktionen',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalReport',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, help_text='ID dieses reports', verbose_name='ID')),
|
||||||
|
('status', models.CharField(choices=[('action taken', 'Action was taken'), ('no action taken', 'No action was taken'), ('waiting', 'Waiting for moderator action')], max_length=30)),
|
||||||
|
('user_comment', models.TextField(blank=True, verbose_name='Kommentar/Zusätzliche Information')),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False, verbose_name='Zuletzt geändert am')),
|
||||||
|
('created_at', models.DateTimeField(blank=True, editable=False, verbose_name='Erstellt am')),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Meldung',
|
||||||
|
'verbose_name_plural': 'historical Meldungen',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalRescueOrganization',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=200)),
|
||||||
|
('trusted', models.BooleanField(default=False, verbose_name='Vertrauenswürdig')),
|
||||||
|
('allows_using_materials', models.CharField(choices=[('allowed', 'Usage allowed'), ('requested', 'Usage requested'), ('denied', 'Usage denied'), ('other', "It's complicated"), ('not_asked', 'Not asked')], default='not_asked', max_length=200, verbose_name='Erlaubt Nutzung von Inhalten')),
|
||||||
|
('location_string', models.CharField(blank=True, max_length=200, null=True, verbose_name='Ort der Organisation')),
|
||||||
|
('instagram', models.URLField(blank=True, null=True, verbose_name='Instagram Profil')),
|
||||||
|
('facebook', models.URLField(blank=True, null=True, verbose_name='Facebook Profil')),
|
||||||
|
('fediverse_profile', models.URLField(blank=True, null=True, verbose_name='Fediverse Profil')),
|
||||||
|
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='E-Mail')),
|
||||||
|
('phone_number', models.CharField(blank=True, max_length=15, null=True, verbose_name='Telefonnummer')),
|
||||||
|
('website', models.URLField(blank=True, null=True, verbose_name='Website')),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('created_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('last_checked', models.DateTimeField(blank=True, editable=False, verbose_name='Datum der letzten Prüfung')),
|
||||||
|
('internal_comment', models.TextField(blank=True, null=True, verbose_name='Interner Kommentar')),
|
||||||
|
('description', models.TextField(blank=True, null=True, verbose_name='Beschreibung')),
|
||||||
|
('external_object_identifier', models.CharField(blank=True, max_length=200, null=True, verbose_name='External Object Identifier')),
|
||||||
|
('external_source_identifier', models.CharField(blank=True, choices=[('OSM', 'Open Street Map')], max_length=200, null=True, verbose_name='External Source Identifier')),
|
||||||
|
('exclude_from_check', models.BooleanField(default=False, help_text='Organisation von der manuellen Überprüfung ausschließen, z.B. weil Tiere nicht online geführt werden', verbose_name='Von Prüfung ausschließen')),
|
||||||
|
('regular_check_status', models.CharField(choices=[('regular_check', 'Wird regelmäßig geprüft'), ('excluded_no_online_listing', 'Exkludiert: Tiere werden nicht online gelistet'), ('excluded_other_org', 'Exkludiert: Andere Organisation wird geprüft'), ('excluded_scope', 'Exkludiert: Organisation hat nie Notfellchen-relevanten Vermittlungen'), ('excluded_other', 'Exkludiert: Anderer Grund')], default='regular_check', help_text='Organisationen können, durch ändern dieser Einstellung, von der regelmäßigen Prüfung ausgeschlossen werden.', max_length=30, verbose_name='Status der regelmäßigen Prüfung')),
|
||||||
|
('ongoing_communication', models.BooleanField(default=False, help_text='Es findet gerade Kommunikation zwischen Notfellchen und der Organisation statt.', verbose_name='In aktiver Kommunikation')),
|
||||||
|
('twenty_id', models.UUIDField(blank=True, help_text='ID der der Organisation in Twenty', null=True, verbose_name='Twenty-ID')),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('location', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.location')),
|
||||||
|
('parent_org', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.rescueorganization')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Tierschutzorganisation',
|
||||||
|
'verbose_name_plural': 'historical Tierschutzorganisationen',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalRule',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('title', models.CharField(max_length=200)),
|
||||||
|
('rule_text', models.TextField(verbose_name='Regeltext')),
|
||||||
|
('rule_identifier', models.CharField(help_text='Ein eindeutiger Identifikator der Regel. Ein Regelobjekt derselben Regel in einer anderen Sprache muss den gleichen Identifikator haben', max_length=24, verbose_name='Regel-ID')),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False, verbose_name='Zuletzt geändert am')),
|
||||||
|
('created_at', models.DateTimeField(blank=True, editable=False, verbose_name='Erstellt am')),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('language', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.language', verbose_name='Sprache')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Regel',
|
||||||
|
'verbose_name_plural': 'historical Regeln',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalSearchSubscription',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('sex', models.CharField(choices=[('F', 'Weiblich'), ('M', 'Männlich'), ('M_N', 'Männlich, kastriert'), ('F_N', 'Weiblich Kastriert'), ('I', 'Intergeschlechtlich'), ('A', 'Alle')], max_length=20, verbose_name='Geschlecht')),
|
||||||
|
('max_distance', models.IntegerField(choices=[(20, '20 km'), (50, '50 km'), (100, '100 km'), (200, '200 km'), (500, '500 km')], null=True)),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False, verbose_name='Zuletzt geändert am')),
|
||||||
|
('created_at', models.DateTimeField(blank=True, editable=False, verbose_name='Erstellt am')),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('location', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.location')),
|
||||||
|
('owner', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Abonnierte Suche',
|
||||||
|
'verbose_name_plural': 'historical Abonnierte Suchen',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalSocialMediaPost',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('created_at', models.DateField(default=django.utils.timezone.now, verbose_name='Erstellt am')),
|
||||||
|
('platform', models.CharField(choices=[('fediverse', 'Fediverse')], max_length=255, verbose_name='Social Media Platform')),
|
||||||
|
('url', models.URLField(verbose_name='URL')),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('adoption_notice', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.adoptionnotice', verbose_name='Vermittlung')),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical social media post',
|
||||||
|
'verbose_name_plural': 'historical social media posts',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalSubscriptions',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('created_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('adoption_notice', models.ForeignKey(blank=True, db_constraint=False, help_text='Vermittlung die abonniert wurde', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.adoptionnotice', verbose_name='Vermittlung')),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('owner', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Nutzer*in')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Abonnement',
|
||||||
|
'verbose_name_plural': 'historical Abonnements',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalText',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('title', models.CharField(max_length=100, verbose_name='Titel')),
|
||||||
|
('content', models.TextField(verbose_name='Inhalt')),
|
||||||
|
('text_code', models.CharField(blank=True, max_length=24, verbose_name='Text code')),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('language', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.language', verbose_name='Sprache')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Text',
|
||||||
|
'verbose_name_plural': 'historical Texte',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HistoricalUser',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||||
|
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||||
|
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||||
|
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||||
|
('username', models.CharField(db_index=True, error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
||||||
|
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
|
||||||
|
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
||||||
|
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
||||||
|
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||||
|
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||||
|
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||||
|
('trust_level', models.IntegerField(choices=[(1, 'Member'), (2, 'Coordinator'), (3, 'Moderator'), (4, 'Admin')], default=1)),
|
||||||
|
('updated_at', models.DateTimeField(blank=True, editable=False)),
|
||||||
|
('reason_for_signup', models.TextField(help_text="Wir würden gerne wissen warum du dich registrierst, ob du dich z.B. Tiere eines bestimmten Tierheim einstellen willst 'nur mal gucken' willst. Beides ist toll! Wenn du für ein Tierheim/eine Pflegestelle arbeitest kontaktieren wir dich ggf. um dir erweiterte Rechte zu geben.", verbose_name='Grund für die Registrierung')),
|
||||||
|
('mod_notes', models.TextField(blank=True, null=True, verbose_name='Moderationsnotizen')),
|
||||||
|
('email_notifications', models.BooleanField(default=True, verbose_name='Benachrichtigung per E-Mail')),
|
||||||
|
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('history_date', models.DateTimeField(db_index=True)),
|
||||||
|
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||||
|
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||||
|
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('organization_affiliation', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.rescueorganization', verbose_name='Organisation')),
|
||||||
|
('preferred_language', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='fellchensammlung.language', verbose_name='Bevorzugte Sprache')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'historical Nutzer*in',
|
||||||
|
'verbose_name_plural': 'historical Nutzer*innen',
|
||||||
|
'ordering': ('-history_date', '-history_id'),
|
||||||
|
'get_latest_by': ('history_date', 'history_id'),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -7,6 +7,7 @@ from django.contrib.auth.models import Group
|
|||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
import base64
|
import base64
|
||||||
|
from simple_history.models import HistoricalRecords
|
||||||
|
|
||||||
from .tools import misc, geo
|
from .tools import misc, geo
|
||||||
from notfellchen.settings import MEDIA_URL, base_url
|
from notfellchen.settings import MEDIA_URL, base_url
|
||||||
@@ -187,6 +188,7 @@ class RescueOrganization(models.Model):
|
|||||||
specializations = models.ManyToManyField(Species, blank=True)
|
specializations = models.ManyToManyField(Species, blank=True)
|
||||||
twenty_id = models.UUIDField(verbose_name=_("Twenty-ID"), null=True, blank=True,
|
twenty_id = models.UUIDField(verbose_name=_("Twenty-ID"), null=True, blank=True,
|
||||||
help_text=_("ID der der Organisation in Twenty"))
|
help_text=_("ID der der Organisation in Twenty"))
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('external_object_identifier', 'external_source_identifier',)
|
unique_together = ('external_object_identifier', 'external_source_identifier',)
|
||||||
@@ -250,6 +252,7 @@ class RescueOrganization(models.Model):
|
|||||||
|
|
||||||
def set_checked(self):
|
def set_checked(self):
|
||||||
self.last_checked = timezone.now()
|
self.last_checked = timezone.now()
|
||||||
|
self._change_reason = 'Organization checked'
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -311,6 +314,7 @@ class User(AbstractUser):
|
|||||||
reason_for_signup = models.TextField(verbose_name=reason_for_signup_label, help_text=reason_for_signup_help_text)
|
reason_for_signup = models.TextField(verbose_name=reason_for_signup_label, help_text=reason_for_signup_help_text)
|
||||||
mod_notes = models.TextField(verbose_name=_("Moderationsnotizen"), null=True, blank=True)
|
mod_notes = models.TextField(verbose_name=_("Moderationsnotizen"), null=True, blank=True)
|
||||||
email_notifications = models.BooleanField(verbose_name=_("Benachrichtigung per E-Mail"), default=True)
|
email_notifications = models.BooleanField(verbose_name=_("Benachrichtigung per E-Mail"), default=True)
|
||||||
|
history = HistoricalRecords()
|
||||||
REQUIRED_FIELDS = ["reason_for_signup", "email"]
|
REQUIRED_FIELDS = ["reason_for_signup", "email"]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@@ -406,6 +410,7 @@ class AdoptionNotice(models.Model):
|
|||||||
adoption_process = models.TextField(null=True, blank=True,
|
adoption_process = models.TextField(null=True, blank=True,
|
||||||
max_length=64, verbose_name=_('Adoptionsprozess'),
|
max_length=64, verbose_name=_('Adoptionsprozess'),
|
||||||
choices=AdoptionProcess)
|
choices=AdoptionProcess)
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def animals(self):
|
def animals(self):
|
||||||
@@ -641,6 +646,7 @@ class Animal(models.Model):
|
|||||||
owner = models.ForeignKey(User, on_delete=models.CASCADE)
|
owner = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.name}"
|
return f"{self.name}"
|
||||||
@@ -704,6 +710,7 @@ class SearchSubscription(models.Model):
|
|||||||
max_distance = models.IntegerField(choices=DistanceChoices.choices, null=True)
|
max_distance = models.IntegerField(choices=DistanceChoices.choices, null=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Zuletzt geändert am"))
|
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Zuletzt geändert am"))
|
||||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Erstellt am"))
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Erstellt am"))
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.location and self.max_distance:
|
if self.location and self.max_distance:
|
||||||
@@ -734,6 +741,7 @@ class Rule(models.Model):
|
|||||||
"Identifikator haben"))
|
"Identifikator haben"))
|
||||||
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Zuletzt geändert am"))
|
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Zuletzt geändert am"))
|
||||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Erstellt am"))
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Erstellt am"))
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
return self.title
|
||||||
@@ -759,6 +767,7 @@ class Report(models.Model):
|
|||||||
user_comment = models.TextField(blank=True, verbose_name=_("Kommentar/Zusätzliche Information"))
|
user_comment = models.TextField(blank=True, verbose_name=_("Kommentar/Zusätzliche Information"))
|
||||||
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Zuletzt geändert am"))
|
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Zuletzt geändert am"))
|
||||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Erstellt am"))
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Erstellt am"))
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"[{self.status}]: {self.user_comment:.20}"
|
return f"[{self.status}]: {self.user_comment:.20}"
|
||||||
@@ -845,6 +854,7 @@ class ModerationAction(models.Model):
|
|||||||
# Only visible to moderator
|
# Only visible to moderator
|
||||||
private_comment = models.TextField(blank=True)
|
private_comment = models.TextField(blank=True)
|
||||||
report = models.ForeignKey(Report, on_delete=models.CASCADE)
|
report = models.ForeignKey(Report, on_delete=models.CASCADE)
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"[{self.action}]: {self.public_comment}"
|
return f"[{self.action}]: {self.public_comment}"
|
||||||
@@ -866,6 +876,7 @@ class Text(models.Model):
|
|||||||
content = models.TextField(verbose_name="Inhalt")
|
content = models.TextField(verbose_name="Inhalt")
|
||||||
language = models.ForeignKey(Language, verbose_name="Sprache", on_delete=models.PROTECT)
|
language = models.ForeignKey(Language, verbose_name="Sprache", on_delete=models.PROTECT)
|
||||||
text_code = models.CharField(max_length=24, verbose_name="Text code", blank=True)
|
text_code = models.CharField(max_length=24, verbose_name="Text code", blank=True)
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Text"
|
verbose_name = "Text"
|
||||||
@@ -909,6 +920,7 @@ class Announcement(Text):
|
|||||||
INFO: "info",
|
INFO: "info",
|
||||||
}
|
}
|
||||||
type = models.CharField(choices=TYPES, max_length=100, default=INFO)
|
type = models.CharField(choices=TYPES, max_length=100, default=INFO)
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_active(self):
|
def is_active(self):
|
||||||
@@ -955,6 +967,7 @@ class Comment(models.Model):
|
|||||||
adoption_notice = models.ForeignKey(AdoptionNotice, on_delete=models.CASCADE, verbose_name=_('Vermittlung'))
|
adoption_notice = models.ForeignKey(AdoptionNotice, on_delete=models.CASCADE, verbose_name=_('Vermittlung'))
|
||||||
text = models.TextField(verbose_name="Inhalt")
|
text = models.TextField(verbose_name="Inhalt")
|
||||||
reply_to = models.ForeignKey("self", verbose_name="Antwort auf", blank=True, null=True, on_delete=models.CASCADE)
|
reply_to = models.ForeignKey("self", verbose_name="Antwort auf", blank=True, null=True, on_delete=models.CASCADE)
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.user} at {self.created_at.strftime('%H:%M %d.%m.%y')}: {self.text:.10}"
|
return f"{self.user} at {self.created_at.strftime('%H:%M %d.%m.%y')}: {self.text:.10}"
|
||||||
@@ -1026,6 +1039,7 @@ class Subscriptions(models.Model):
|
|||||||
help_text=_("Vermittlung die abonniert wurde"))
|
help_text=_("Vermittlung die abonniert wurde"))
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.owner} - {self.adoption_notice}"
|
return f"{self.owner} - {self.adoption_notice}"
|
||||||
@@ -1087,6 +1101,7 @@ class SocialMediaPost(models.Model):
|
|||||||
choices=PlatformChoices.choices)
|
choices=PlatformChoices.choices)
|
||||||
adoption_notice = models.ForeignKey(AdoptionNotice, on_delete=models.CASCADE, verbose_name=_('Vermittlung'))
|
adoption_notice = models.ForeignKey(AdoptionNotice, on_delete=models.CASCADE, verbose_name=_('Vermittlung'))
|
||||||
url = models.URLField(verbose_name=_("URL"))
|
url = models.URLField(verbose_name=_("URL"))
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_an_to_post():
|
def get_an_to_post():
|
||||||
|
|||||||
@@ -237,6 +237,7 @@ INSTALLED_APPS = [
|
|||||||
'widget_tweaks',
|
'widget_tweaks',
|
||||||
"debug_toolbar",
|
"debug_toolbar",
|
||||||
'admin_extra_buttons',
|
'admin_extra_buttons',
|
||||||
|
'simple_history',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@@ -254,6 +255,7 @@ MIDDLEWARE = [
|
|||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
# allauth middleware, needs to be after message middleware
|
# allauth middleware, needs to be after message middleware
|
||||||
"allauth.account.middleware.AccountMiddleware",
|
"allauth.account.middleware.AccountMiddleware",
|
||||||
|
'simple_history.middleware.HistoryRequestMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'notfellchen.urls'
|
ROOT_URLCONF = 'notfellchen.urls'
|
||||||
|
|||||||
Reference in New Issue
Block a user