発散解像度 -divergence resolution-

Signed-off-by: Shin'ya Minazuki <shinyoukai@laidback.moe>
This commit is contained in:
Shin'ya Minazuki 2026-01-25 21:15:56 +01:00
commit 01bb65f8da
457 changed files with 929 additions and 602 deletions

View file

@ -0,0 +1,137 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone
import django.contrib.auth.models
import django.core.validators
class Migration(migrations.Migration):
dependencies = [("auth", "0006_require_contenttypes_0002")]
operations = [
migrations.CreateModel(
name="User",
fields=[
(
"id",
models.AutoField(
primary_key=True,
verbose_name="ID",
serialize=False,
auto_created=True,
),
),
("password", models.CharField(max_length=128, verbose_name="password")),
(
"last_login",
models.DateTimeField(
null=True, verbose_name="last login", blank=True
),
),
(
"is_superuser",
models.BooleanField(
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
default=False,
),
),
(
"username",
models.CharField(
max_length=30,
validators=[
django.core.validators.RegexValidator(
"^[\\w.@+-]+$",
"Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.",
"invalid",
)
],
verbose_name="username",
error_messages={
"unique": "A user with that username already exists."
},
help_text="Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.",
unique=True,
),
),
(
"first_name",
models.CharField(
max_length=30, verbose_name="first name", blank=True
),
),
(
"last_name",
models.CharField(
max_length=30, verbose_name="last name", blank=True
),
),
(
"email",
models.EmailField(
max_length=254, verbose_name="email address", blank=True
),
),
(
"is_staff",
models.BooleanField(
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
default=False,
),
),
(
"is_active",
models.BooleanField(
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
verbose_name="active",
default=True,
),
),
(
"date_joined",
models.DateTimeField(
verbose_name="date joined", default=django.utils.timezone.now
),
),
(
"groups",
models.ManyToManyField(
related_name="user_set",
blank=True,
verbose_name="groups",
to="auth.Group",
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
related_query_name="user",
),
),
(
"user_permissions",
models.ManyToManyField(
related_name="user_set",
blank=True,
verbose_name="user permissions",
to="auth.Permission",
help_text="Specific permissions for this user.",
related_query_name="user",
),
),
(
"name",
models.CharField(
max_length=255, verbose_name="Name of User", blank=True
),
),
],
options={
"verbose_name": "user",
"abstract": False,
"verbose_name_plural": "users",
},
managers=[("objects", django.contrib.auth.models.UserManager())],
)
]

View file

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-12-14 22:05
from __future__ import unicode_literals
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("users", "0001_initial")]
operations = [
migrations.AlterModelManagers(
name="user",
managers=[("objects", django.contrib.auth.models.UserManager())],
),
migrations.AlterField(
model_name="user",
name="username",
field=models.CharField(
error_messages={"unique": "A user with that username already exists."},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()],
verbose_name="username",
),
),
]

View file

@ -0,0 +1,24 @@
# Generated by Django 2.0 on 2017-12-26 13:57
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [("users", "0002_auto_20171214_2205")]
operations = [
migrations.AddField(
model_name="user",
name="secret_key",
field=models.UUIDField(default=uuid.uuid4, null=True),
),
migrations.AlterField(
model_name="user",
name="last_name",
field=models.CharField(
blank=True, max_length=150, verbose_name="last name"
),
),
]

View file

@ -0,0 +1,25 @@
# Generated by Django 2.0.2 on 2018-03-01 19:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("users", "0003_auto_20171226_1357")]
operations = [
migrations.AddField(
model_name="user",
name="privacy_level",
field=models.CharField(
choices=[
("me", "Only me"),
("followers", "Me and my followers"),
("instance", "Everyone on my instance, and my followers"),
("everyone", "Everyone, including people on other instances"),
],
default="instance",
max_length=30,
),
)
]

View file

@ -0,0 +1,16 @@
# Generated by Django 2.0.3 on 2018-05-08 09:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("users", "0004_user_privacy_level")]
operations = [
migrations.AddField(
model_name="user",
name="subsonic_api_token",
field=models.CharField(blank=True, max_length=255, null=True),
)
]

View file

@ -0,0 +1,26 @@
# Generated by Django 2.0.4 on 2018-05-17 23:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("users", "0005_user_subsonic_api_token")]
operations = [
migrations.AddField(
model_name="user",
name="permission_federation",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name="user",
name="permission_library",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name="user",
name="permission_settings",
field=models.BooleanField(default=False),
),
]

View file

@ -0,0 +1,41 @@
# Generated by Django 2.0.4 on 2018-05-24 20:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("users", "0006_auto_20180517_2324")]
operations = [
migrations.AddField(
model_name="user",
name="permission_upload",
field=models.BooleanField(
default=False, verbose_name="Upload new content to the library"
),
),
migrations.AlterField(
model_name="user",
name="permission_federation",
field=models.BooleanField(
default=False,
help_text="Follow other instances, accept/deny library follow requests...",
verbose_name="Manage library federation",
),
),
migrations.AlterField(
model_name="user",
name="permission_library",
field=models.BooleanField(
default=False, help_text="Manage library", verbose_name="Manage library"
),
),
migrations.AlterField(
model_name="user",
name="permission_settings",
field=models.BooleanField(
default=False, verbose_name="Manage instance-level settings"
),
),
]

View file

@ -0,0 +1,25 @@
# Generated by Django 2.0.6 on 2018-06-17 15:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("users", "0007_auto_20180524_2009")]
operations = [
migrations.AddField(
model_name="user",
name="last_activity",
field=models.DateTimeField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name="user",
name="permission_library",
field=models.BooleanField(
default=False,
help_text="Manage library, delete files, tracks, artists, albums...",
verbose_name="Manage library",
),
),
]

View file

@ -0,0 +1,53 @@
# Generated by Django 2.0.6 on 2018-06-19 20:24
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [("users", "0008_auto_20180617_1531")]
operations = [
migrations.CreateModel(
name="Invitation",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"creation_date",
models.DateTimeField(default=django.utils.timezone.now),
),
("expiration_date", models.DateTimeField()),
("code", models.CharField(max_length=50, unique=True)),
(
"owner",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="invitations",
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.AddField(
model_name="user",
name="invitation",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="users",
to="users.Invitation",
),
),
]

View file

@ -0,0 +1,28 @@
# Generated by Django 2.0.6 on 2018-07-10 20:09
from django.db import migrations, models
import funkwhale_api.common.utils
import funkwhale_api.common.validators
class Migration(migrations.Migration):
dependencies = [("users", "0009_auto_20180619_2024")]
operations = [
migrations.AddField(
model_name="user",
name="avatar",
field=models.ImageField(
blank=True,
max_length=150,
null=True,
upload_to=funkwhale_api.common.utils.ChunkedPath("users/avatars"),
validators=[
funkwhale_api.common.validators.ImageDimensionsValidator(
max_height=400, max_width=400, min_height=50, min_width=50
)
],
),
)
]

View file

@ -0,0 +1,50 @@
# Generated by Django 2.0.7 on 2018-07-21 13:17
from django.db import migrations, models
import django.db.models.deletion
import funkwhale_api.common.utils
import funkwhale_api.common.validators
import versatileimagefield.fields
class Migration(migrations.Migration):
dependencies = [
("federation", "0006_auto_20180521_1702"),
("users", "0010_user_avatar"),
]
operations = [
migrations.AddField(
model_name="user",
name="actor",
field=models.OneToOneField(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="user",
to="federation.Actor",
),
),
migrations.AlterField(
model_name="user",
name="avatar",
field=versatileimagefield.fields.VersatileImageField(
blank=True,
max_length=150,
null=True,
upload_to=funkwhale_api.common.utils.ChunkedPath(
"users/avatars", preserve_file_name=False
),
validators=[
funkwhale_api.common.validators.ImageDimensionsValidator(
min_height=50, min_width=50
),
funkwhale_api.common.validators.FileValidator(
allowed_extensions=["png", "jpg", "jpeg", "gif"],
max_size=2097152,
),
],
),
),
]

View file

@ -0,0 +1,16 @@
# Generated by Django 2.0.7 on 2018-08-01 16:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("users", "0011_auto_20180721_1317")]
operations = [
migrations.AddField(
model_name="user",
name="upload_quota",
field=models.PositiveIntegerField(blank=True, null=True),
)
]

View file

@ -0,0 +1,26 @@
# Generated by Django 2.0.9 on 2018-12-06 10:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0012_user_upload_quota'),
]
operations = [
migrations.RemoveField(
model_name='user',
name='permission_federation',
),
migrations.RemoveField(
model_name='user',
name='permission_upload',
),
migrations.AddField(
model_name='user',
name='permission_moderation',
field=models.BooleanField(default=False, help_text='Block/mute/remove domains, users and content', verbose_name='Moderation'),
),
]

View file

@ -0,0 +1,195 @@
# Generated by Django 2.0.9 on 2018-12-06 10:08
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
import oauth2_provider.generators
class Migration(migrations.Migration):
dependencies = [
("users", "0013_auto_20181206_1008"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="AccessToken",
fields=[
("id", models.BigAutoField(primary_key=True, serialize=False)),
("expires", models.DateTimeField()),
("scope", models.TextField(blank=True)),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
("token", models.CharField(max_length=255, unique=True)),
],
options={"abstract": False},
),
migrations.CreateModel(
name="Application",
fields=[
("id", models.BigAutoField(primary_key=True, serialize=False)),
(
"client_id",
models.CharField(
db_index=True,
default=oauth2_provider.generators.generate_client_id,
max_length=100,
unique=True,
),
),
(
"redirect_uris",
models.TextField(
blank=True, help_text="Allowed URIs list, space separated"
),
),
(
"client_type",
models.CharField(
choices=[
("confidential", "Confidential"),
("public", "Public"),
],
max_length=32,
),
),
(
"authorization_grant_type",
models.CharField(
choices=[
("authorization-code", "Authorization code"),
("implicit", "Implicit"),
("password", "Resource owner password-based"),
("client-credentials", "Client credentials"),
],
max_length=32,
),
),
(
"client_secret",
models.CharField(
blank=True,
db_index=True,
default=oauth2_provider.generators.generate_client_secret,
max_length=255,
),
),
("name", models.CharField(blank=True, max_length=255)),
("skip_authorization", models.BooleanField(default=False)),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
(
"user",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="users_application",
to=settings.AUTH_USER_MODEL,
),
),
],
options={"abstract": False},
),
migrations.CreateModel(
name="Grant",
fields=[
("id", models.BigAutoField(primary_key=True, serialize=False)),
("code", models.CharField(max_length=255, unique=True)),
("expires", models.DateTimeField()),
("redirect_uri", models.CharField(max_length=255)),
("scope", models.TextField(blank=True)),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
(
"application",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="users.Application",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="users_grant",
to=settings.AUTH_USER_MODEL,
),
),
],
options={"abstract": False},
),
migrations.CreateModel(
name="RefreshToken",
fields=[
("id", models.BigAutoField(primary_key=True, serialize=False)),
("token", models.CharField(max_length=255)),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
("revoked", models.DateTimeField(null=True)),
(
"access_token",
models.OneToOneField(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="refresh_token",
to="users.AccessToken",
),
),
(
"application",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="users.Application",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="users_refreshtoken",
to=settings.AUTH_USER_MODEL,
),
),
],
options={"abstract": False},
),
migrations.AddField(
model_name="accesstoken",
name="application",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="users.Application",
),
),
migrations.AddField(
model_name="accesstoken",
name="source_refresh_token",
field=models.OneToOneField(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="refreshed_access_token",
to="users.RefreshToken",
),
),
migrations.AddField(
model_name="accesstoken",
name="user",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="users_accesstoken",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AlterUniqueTogether(
name="refreshtoken", unique_together={("token", "revoked")}
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 2.1.7 on 2019-03-18 09:36
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0014_oauth'),
]
operations = [
migrations.AddField(
model_name='application',
name='scope',
field=models.TextField(blank=True),
),
]

View file

@ -0,0 +1,47 @@
# Generated by Django 2.2.4 on 2019-09-20 08:57
import datetime
from django.conf import settings
from django.db import migrations, models
import django.utils.timezone
import funkwhale_api.users.models
def set_display_date(apps, schema_editor):
"""
Set display date for instance/funkwhale support message on existing users
"""
User = apps.get_model("users", "User")
now = django.utils.timezone.now()
instance_support_message_display_date = now + datetime.timedelta(days=settings.INSTANCE_SUPPORT_MESSAGE_DELAY)
funkwhale_support_message_display_date = now + datetime.timedelta(days=settings.FUNQUAIL_SUPPORT_MESSAGE_DELAY)
User.objects.update(instance_support_message_display_date=instance_support_message_display_date)
User.objects.update(funkwhale_support_message_display_date=funkwhale_support_message_display_date)
def rewind(*args, **kwargs):
pass
class Migration(migrations.Migration):
dependencies = [
('users', '0015_application_scope'),
]
operations = [
migrations.AddField(
model_name='user',
name='funkwhale_support_message_display_date',
field=models.DateTimeField(blank=True, null=True, default=funkwhale_api.users.models.get_default_funkwhale_support_message_display_date),
),
migrations.AddField(
model_name='user',
name='instance_support_message_display_date',
field=models.DateTimeField(blank=True, null=True, default=funkwhale_api.users.models.get_default_instance_support_message_display_date),
),
migrations.RunPython(set_display_date, rewind),
]

View file

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
def create_attachments(apps, schema_editor):
Actor = apps.get_model("federation", "Actor")
User = apps.get_model("users", "User")
Attachment = apps.get_model("common", "Attachment")
obj_attachment_mapping = {}
def get_mimetype(path):
if path.lower().endswith('.png'):
return "image/png"
return "image/jpeg"
qs = User.objects.filter(actor__attachment_icon=None).exclude(avatar="").exclude(avatar=None).exclude(actor=None).select_related('actor')
total = qs.count()
print('Creating attachments for {} user avatars, this may take a while…'.format(total))
from django.core.files.storage import FileSystemStorage
for i, user in enumerate(qs):
size = None
if isinstance(user.avatar.storage._wrapped, FileSystemStorage):
try:
size = user.avatar.size
except FileNotFoundError:
# can occur when file isn't found on disk or S3
print(" Warning: avatar file wasn't found in storage: {}".format(e.__class__))
obj_attachment_mapping[user.actor] = Attachment(
file=user.avatar,
size=size,
mimetype=get_mimetype(user.avatar.name),
)
print('Commiting changes…')
Attachment.objects.bulk_create(obj_attachment_mapping.values(), batch_size=2000)
# map each attachment to the corresponding obj
# and bulk save
for obj, attachment in obj_attachment_mapping.items():
obj.attachment_icon = attachment
Actor.objects.bulk_update(obj_attachment_mapping.keys(), fields=['attachment_icon'], batch_size=2000)
def rewind(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [("users", "0016_auto_20190920_0857"), ("federation", "0024_actor_attachment_icon")]
operations = [migrations.RunPython(create_attachments, rewind)]

View file

@ -0,0 +1,26 @@
# Generated by Django 3.0.8 on 2020-07-05 08:29
import django.contrib.postgres.fields.jsonb
from django.db import migrations
import funkwhale_api.users.models
class Migration(migrations.Migration):
dependencies = [
('users', '0017_actor_avatar'),
]
operations = [
migrations.AlterModelManagers(
name='user',
managers=[
('objects', funkwhale_api.users.models.UserManager()),
],
),
migrations.AddField(
model_name='user',
name='settings',
field=django.contrib.postgres.fields.jsonb.JSONField(default=None, null=True, blank=True, max_length=50000),
),
]

View file

@ -0,0 +1,23 @@
# Generated by Django 3.0.8 on 2020-07-18 07:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0018_auto_20200705_0829'),
]
operations = [
migrations.AddField(
model_name='grant',
name='code_challenge',
field=models.CharField(blank=True, default='', max_length=128),
),
migrations.AddField(
model_name='grant',
name='code_challenge_method',
field=models.CharField(blank=True, choices=[('plain', 'plain'), ('S256', 'S256')], default='', max_length=10),
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 3.0.8 on 2020-08-19 08:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0019_auto_20200718_0741'),
]
operations = [
migrations.AddField(
model_name='application',
name='token',
field=models.CharField(blank=True, max_length=50, null=True, unique=True),
),
]

View file

@ -0,0 +1,67 @@
# Generated by Django 3.2.4 on 2021-07-03 18:10
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
('users', '0020_application_token'),
]
operations = [
migrations.AddField(
model_name='application',
name='algorithm',
field=models.CharField(blank=True, choices=[('', 'No OIDC support'), ('RS256', 'RSA with SHA-2 256'), ('HS256', 'HMAC with SHA-2 256')], default='', max_length=5),
),
migrations.AddField(
model_name='grant',
name='claims',
field=models.TextField(blank=True),
),
migrations.AddField(
model_name='grant',
name='nonce',
field=models.CharField(blank=True, default='', max_length=255),
),
migrations.AlterField(
model_name='application',
name='authorization_grant_type',
field=models.CharField(choices=[('authorization-code', 'Authorization code'), ('implicit', 'Implicit'), ('password', 'Resource owner password-based'), ('client-credentials', 'Client credentials'), ('openid-hybrid', 'OpenID connect hybrid')], max_length=32),
),
migrations.AlterField(
model_name='grant',
name='redirect_uri',
field=models.TextField(),
),
migrations.AlterField(
model_name='user',
name='first_name',
field=models.CharField(blank=True, max_length=150, verbose_name='first name'),
),
migrations.CreateModel(
name='IdToken',
fields=[
('id', models.BigAutoField(primary_key=True, serialize=False)),
('jti', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='JWT Token ID')),
('expires', models.DateTimeField()),
('scope', models.TextField(blank=True)),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('application', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL)),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='users_idtoken', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='accesstoken',
name='id_token',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='access_token', to=settings.OAUTH2_PROVIDER_ID_TOKEN_MODEL),
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 3.2.13 on 2022-06-27 19:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0021_auto_20210703_1810'),
]
operations = [
migrations.AlterField(
model_name='user',
name='settings',
field=models.JSONField(blank=True, default=None, max_length=50000, null=True),
),
]

View file

@ -0,0 +1,37 @@
# Generated by Django 3.2.16 on 2022-11-19 18:19
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
def update_invitation_table(apps, schema_editor):
User = apps.get_model("users", "User")
Invitation = apps.get_model("users", "Invitation")
for user in User.objects.all():
if user.invitation:
Invitation.objects.filter(id=user.invitation.id).update(invited_user_id=user.id)
def rewind(*args, **kwargs):
pass
class Migration(migrations.Migration):
dependencies = [
('users', '0021_auto_20210703_1810'),
]
operations = [
migrations.AddField(
model_name='invitation',
name='invited_user',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='user_invitations', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='invitation',
name='owner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invitations', to=settings.AUTH_USER_MODEL),
),
migrations.RunPython(update_invitation_table, rewind),
]

View file

@ -0,0 +1,14 @@
# Generated by Django 3.2.16 on 2022-11-25 19:02
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('users', '0022_alter_user_settings'),
('users', '0022_auto_20221119_1819'),
]
operations = [
]