membershipworks: Use django-simple-history for Member, Flag, and MemberFlag
This commit is contained in:
parent
ee61451759
commit
b98804e514
@ -54,6 +54,7 @@ class Base(Configuration):
|
|||||||
"django_db_views",
|
"django_db_views",
|
||||||
"django_sendfile",
|
"django_sendfile",
|
||||||
"django_bootstrap5",
|
"django_bootstrap5",
|
||||||
|
"simple_history",
|
||||||
# "tasks.apps.TasksConfig",
|
# "tasks.apps.TasksConfig",
|
||||||
"rentals.apps.RentalsConfig",
|
"rentals.apps.RentalsConfig",
|
||||||
"membershipworks.apps.MembershipworksConfig",
|
"membershipworks.apps.MembershipworksConfig",
|
||||||
|
@ -10,6 +10,7 @@ from django_object_actions import (
|
|||||||
)
|
)
|
||||||
from django_q.models import Task
|
from django_q.models import Task
|
||||||
from django_q.tasks import async_task
|
from django_q.tasks import async_task
|
||||||
|
from simple_history.admin import SimpleHistoryAdmin
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Event,
|
Event,
|
||||||
@ -28,7 +29,7 @@ from .tasks.scrape import (
|
|||||||
from .tasks.ucsAccounts import sync_accounts
|
from .tasks.ucsAccounts import sync_accounts
|
||||||
|
|
||||||
|
|
||||||
class ReadOnlyAdmin(admin.ModelAdmin):
|
class ReadOnlyAdminMixin:
|
||||||
def has_add_permission(self, request, obj=None):
|
def has_add_permission(self, request, obj=None):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -39,7 +40,9 @@ class ReadOnlyAdmin(admin.ModelAdmin):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class BaseMembershipWorksAdmin(DjangoObjectActions, ReadOnlyAdmin):
|
class BaseMembershipWorksAdmin(
|
||||||
|
DjangoObjectActions, ReadOnlyAdminMixin, SimpleHistoryAdmin
|
||||||
|
):
|
||||||
changelist_actions = ("refresh_membershipworks_data", "sync_ucs_accounts")
|
changelist_actions = ("refresh_membershipworks_data", "sync_ucs_accounts")
|
||||||
|
|
||||||
# internal method from DjangoObjectActions
|
# internal method from DjangoObjectActions
|
||||||
|
453
membershipworks/migrations/0002_historical_member_and_flags.py
Normal file
453
membershipworks/migrations/0002_historical_member_and_flags.py
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
# Generated by Django 5.1 on 2024-08-28 19:20
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import simple_history.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("membershipworks", "0001_initial"),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="HistoricalFlag",
|
||||||
|
fields=[
|
||||||
|
("id", models.CharField(db_index=True, max_length=24)),
|
||||||
|
("name", models.TextField(blank=True, null=True)),
|
||||||
|
("type", models.CharField(max_length=6)),
|
||||||
|
("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 flag",
|
||||||
|
"verbose_name_plural": "historical flags",
|
||||||
|
"ordering": ("-history_date", "-history_id"),
|
||||||
|
"get_latest_by": ("history_date", "history_id"),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="HistoricalMember",
|
||||||
|
fields=[
|
||||||
|
("uid", models.CharField(db_index=True, max_length=24)),
|
||||||
|
(
|
||||||
|
"year_of_birth",
|
||||||
|
models.TextField(blank=True, db_column="Year of Birth", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"account_name",
|
||||||
|
models.TextField(blank=True, db_column="Account Name", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"first_name",
|
||||||
|
models.TextField(blank=True, db_column="First Name", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"last_name",
|
||||||
|
models.TextField(blank=True, db_column="Last Name", null=True),
|
||||||
|
),
|
||||||
|
("phone", models.TextField(blank=True, db_column="Phone", null=True)),
|
||||||
|
("email", models.TextField(blank=True, db_column="Email", null=True)),
|
||||||
|
(
|
||||||
|
"volunteer_email",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Volunteer Email", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"address_street",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Address (Street)", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"address_city",
|
||||||
|
models.TextField(blank=True, db_column="Address (City)", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"address_state_province",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Address (State/Province)", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"address_postal_code",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Address (Postal Code)", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"address_country",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Address (Country)", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"profile_description",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Profile description", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"website",
|
||||||
|
models.TextField(blank=True, db_column="Website", null=True),
|
||||||
|
),
|
||||||
|
("fax", models.TextField(blank=True, db_column="Fax", null=True)),
|
||||||
|
(
|
||||||
|
"contact_person",
|
||||||
|
models.TextField(blank=True, db_column="Contact Person", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"password",
|
||||||
|
models.TextField(blank=True, db_column="Password", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"position_relation",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Position/relation", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"parent_account_id",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Parent Account ID", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"closet_storage",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Closet Storage #", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"storage_shelf",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Storage Shelf #", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"personal_studio_space",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Personal Studio Space #", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_permitted_shops_during_extended_hours",
|
||||||
|
models.BooleanField(
|
||||||
|
db_column="Access Permitted Shops During Extended Hours?"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_front_door_and_studio_space_during_extended_hours",
|
||||||
|
models.BooleanField(
|
||||||
|
db_column="Access Front Door and Studio Space During Extended Hours?"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_wood_shop",
|
||||||
|
models.BooleanField(db_column="Access Wood Shop?"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_metal_shop",
|
||||||
|
models.BooleanField(db_column="Access Metal Shop?"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_storage_closet",
|
||||||
|
models.BooleanField(db_column="Access Storage Closet?"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_studio_space",
|
||||||
|
models.BooleanField(db_column="Access Studio Space?"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_front_door",
|
||||||
|
models.BooleanField(db_column="Access Front Door?"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_card_number",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Access Card Number", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_card_facility_code",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Access Card Facility Code", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"auto_billing_id",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Auto Billing ID", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"billing_method",
|
||||||
|
models.TextField(blank=True, db_column="Billing Method", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"renewal_date",
|
||||||
|
models.DateField(blank=True, db_column="Renewal Date", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"join_date",
|
||||||
|
models.DateField(blank=True, db_column="Join Date", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"admin_note",
|
||||||
|
models.TextField(blank=True, db_column="Admin note", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"profile_gallery_image_url",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Profile gallery image URL", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"business_card_image_url",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Business card image URL", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"instagram",
|
||||||
|
models.TextField(blank=True, db_column="Instagram", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"pinterest",
|
||||||
|
models.TextField(blank=True, db_column="Pinterest", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"youtube",
|
||||||
|
models.TextField(blank=True, db_column="Youtube", null=True),
|
||||||
|
),
|
||||||
|
("yelp", models.TextField(blank=True, db_column="Yelp", null=True)),
|
||||||
|
(
|
||||||
|
"google",
|
||||||
|
models.TextField(blank=True, db_column="Google+", null=True),
|
||||||
|
),
|
||||||
|
("bbb", models.TextField(blank=True, db_column="BBB", null=True)),
|
||||||
|
(
|
||||||
|
"twitter",
|
||||||
|
models.TextField(blank=True, db_column="Twitter", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"facebook",
|
||||||
|
models.TextField(blank=True, db_column="Facebook", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"linked_in",
|
||||||
|
models.TextField(blank=True, db_column="LinkedIn", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"do_not_show_street_address_in_profile",
|
||||||
|
models.TextField(
|
||||||
|
blank=True,
|
||||||
|
db_column="Do not show street address in profile",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"do_not_list_in_directory",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Do not list in directory", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"how_did_you_hear",
|
||||||
|
models.TextField(blank=True, db_column="HowDidYouHear", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"authorize_charge",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="authorizeCharge", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"policy_agreement",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="policyAgreement", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"waiver_form_signed_and_on_file_date",
|
||||||
|
models.DateField(
|
||||||
|
blank=True,
|
||||||
|
db_column="Waiver form signed and on file date.",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"membership_agreement_signed_and_on_file_date",
|
||||||
|
models.DateField(
|
||||||
|
blank=True,
|
||||||
|
db_column="Membership Agreement signed and on file date.",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ip_address",
|
||||||
|
models.TextField(blank=True, db_column="IP Address", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"audit_date",
|
||||||
|
models.DateField(blank=True, db_column="Audit Date", null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"agreement_version",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Agreement Version", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"paperwork_status",
|
||||||
|
models.TextField(
|
||||||
|
blank=True, db_column="Paperwork status", null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"membership_agreement_dated",
|
||||||
|
models.BooleanField(db_column="Membership agreement dated"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"membership_agreement_acknowledgement_page_filled_out",
|
||||||
|
models.BooleanField(
|
||||||
|
db_column="Membership Agreement Acknowledgement Page Filled Out"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"membership_agreement_signed",
|
||||||
|
models.BooleanField(db_column="Membership Agreement Signed"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"liability_form_filled_out",
|
||||||
|
models.BooleanField(db_column="Liability Form Filled Out"),
|
||||||
|
),
|
||||||
|
("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 member",
|
||||||
|
"verbose_name_plural": "historical members",
|
||||||
|
"ordering": ("-history_date", "-history_id"),
|
||||||
|
"get_latest_by": ("history_date", "history_id"),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="HistoricalMemberFlag",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigIntegerField(
|
||||||
|
auto_created=True, blank=True, db_index=True, verbose_name="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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"flag",
|
||||||
|
simple_history.models.HistoricForeignKey(
|
||||||
|
blank=True,
|
||||||
|
db_constraint=False,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
||||||
|
related_name="+",
|
||||||
|
to="membershipworks.flag",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"history_user",
|
||||||
|
models.ForeignKey(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name="+",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"member",
|
||||||
|
simple_history.models.HistoricForeignKey(
|
||||||
|
blank=True,
|
||||||
|
db_column="uid",
|
||||||
|
db_constraint=False,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
||||||
|
related_name="+",
|
||||||
|
to="membershipworks.member",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"verbose_name": "historical member flag",
|
||||||
|
"verbose_name_plural": "historical member flags",
|
||||||
|
"ordering": ("-history_date", "-history_id"),
|
||||||
|
"get_latest_by": ("history_date", "history_id"),
|
||||||
|
},
|
||||||
|
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="memberflag",
|
||||||
|
name="flag",
|
||||||
|
field=simple_history.models.HistoricForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT, to="membershipworks.flag"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="memberflag",
|
||||||
|
name="member",
|
||||||
|
field=simple_history.models.HistoricForeignKey(
|
||||||
|
db_column="uid",
|
||||||
|
db_constraint=False,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to="membershipworks.member",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
@ -28,6 +28,7 @@ from django.utils import timezone
|
|||||||
import nh3
|
import nh3
|
||||||
from django_db_views.db_view import DBView
|
from django_db_views.db_view import DBView
|
||||||
from django_stubs_ext import WithAnnotations
|
from django_stubs_ext import WithAnnotations
|
||||||
|
from simple_history.models import HistoricalRecords, HistoricForeignKey
|
||||||
|
|
||||||
from reservations.models import Reservation
|
from reservations.models import Reservation
|
||||||
|
|
||||||
@ -89,6 +90,8 @@ class Flag(BaseModel):
|
|||||||
name = models.TextField(null=True, blank=True)
|
name = models.TextField(null=True, blank=True)
|
||||||
type = models.CharField(max_length=6)
|
type = models.CharField(max_length=6)
|
||||||
|
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "flag"
|
db_table = "flag"
|
||||||
ordering = ("name",)
|
ordering = ("name",)
|
||||||
@ -121,7 +124,6 @@ class MemberQuerySet(models.QuerySet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# TODO: is this still a temporal table?
|
|
||||||
class Member(BaseModel):
|
class Member(BaseModel):
|
||||||
uid = models.CharField(max_length=24, primary_key=True)
|
uid = models.CharField(max_length=24, primary_key=True)
|
||||||
year_of_birth = models.TextField(db_column="Year of Birth", null=True, blank=True)
|
year_of_birth = models.TextField(db_column="Year of Birth", null=True, blank=True)
|
||||||
@ -248,6 +250,8 @@ class Member(BaseModel):
|
|||||||
)
|
)
|
||||||
flags = models.ManyToManyField(Flag, through="MemberFlag", related_name="members")
|
flags = models.ManyToManyField(Flag, through="MemberFlag", related_name="members")
|
||||||
|
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
_api_names_override = {
|
_api_names_override = {
|
||||||
"uid": "Account ID",
|
"uid": "Account ID",
|
||||||
"how_did_you_hear": "Please tell us how you heard about the Claremont MakerSpace and what tools or shops you are most excited to start using:",
|
"how_did_you_hear": "Please tell us how you heard about the Claremont MakerSpace and what tools or shops you are most excited to start using:",
|
||||||
@ -300,10 +304,12 @@ class Member(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class MemberFlag(BaseModel):
|
class MemberFlag(BaseModel):
|
||||||
member = models.ForeignKey(
|
member = HistoricForeignKey(
|
||||||
Member, on_delete=models.PROTECT, db_column="uid", db_constraint=False
|
Member, on_delete=models.PROTECT, db_column="uid", db_constraint=False
|
||||||
)
|
)
|
||||||
flag = models.ForeignKey(Flag, on_delete=models.PROTECT)
|
flag = HistoricForeignKey(Flag, on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
history = HistoricalRecords()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "memberflag"
|
db_table = "memberflag"
|
||||||
|
17
pdm.lock
17
pdm.lock
@ -5,7 +5,7 @@
|
|||||||
groups = ["default", "debug", "dev", "lint", "server", "typing"]
|
groups = ["default", "debug", "dev", "lint", "server", "typing"]
|
||||||
strategy = ["inherit_metadata"]
|
strategy = ["inherit_metadata"]
|
||||||
lock_version = "4.5.0"
|
lock_version = "4.5.0"
|
||||||
content_hash = "sha256:0c560e1f2a81810e95ba8993538337bfc8b39576b6923280cfbfad91ad5b58f2"
|
content_hash = "sha256:f908c755f35f0769821be54914ad53a3de6e9a0c654baf877045c161c7dacfc7"
|
||||||
|
|
||||||
[[metadata.targets]]
|
[[metadata.targets]]
|
||||||
requires_python = "==3.11.*"
|
requires_python = "==3.11.*"
|
||||||
@ -650,6 +650,21 @@ files = [
|
|||||||
{file = "django_sendfile2-0.7.1-py3-none-any.whl", hash = "sha256:81971df1db77f688c4834b8540930902d0d929c64cf374bd604b81f5ac52c04a"},
|
{file = "django_sendfile2-0.7.1-py3-none-any.whl", hash = "sha256:81971df1db77f688c4834b8540930902d0d929c64cf374bd604b81f5ac52c04a"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "django-simple-history"
|
||||||
|
version = "3.7.0"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "Store model history and view/revert changes from admin site."
|
||||||
|
groups = ["default"]
|
||||||
|
marker = "python_version == \"3.11\""
|
||||||
|
dependencies = [
|
||||||
|
"django>=4.2",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "django_simple_history-3.7.0-py3-none-any.whl", hash = "sha256:282cb2c4aa63f51547f17da7f2130abaa81ba01694676d19b88d52c94a57a52c"},
|
||||||
|
{file = "django_simple_history-3.7.0.tar.gz", hash = "sha256:ac3b7ca8b0d33f7ea6be8fe7fc98cf43415efa500ff5dfe736fbd1ebc0cf39f9"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django-stubs"
|
name = "django-stubs"
|
||||||
version = "5.0.2"
|
version = "5.0.2"
|
||||||
|
@ -43,6 +43,7 @@ dependencies = [
|
|||||||
"google-auth-oauthlib~=1.2",
|
"google-auth-oauthlib~=1.2",
|
||||||
"django-model-utils~=4.5",
|
"django-model-utils~=4.5",
|
||||||
"psycopg[binary,pool]~=3.2",
|
"psycopg[binary,pool]~=3.2",
|
||||||
|
"django-simple-history~=3.7",
|
||||||
]
|
]
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user