fnschool 20251021.80058.842__py3-none-any.whl → 20251027.82134.859__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fnschool might be problematic. Click here for more details.
- fnschoo1/__init__.py +1 -1
- fnschoo1/canteen/forms.py +2 -2
- fnschoo1/canteen/migrations/0019_category_updated_at_ingredient_created_at_and_more.py +48 -0
- fnschoo1/canteen/migrations/0020_alter_ingredient_created_at.py +20 -0
- fnschoo1/canteen/models.py +23 -3
- fnschoo1/canteen/templates/canteen/category/list.html +1 -1
- fnschoo1/canteen/templates/canteen/consumption/create.html +6 -1
- fnschoo1/canteen/templates/canteen/ingredient/list.html +11 -2
- fnschoo1/canteen/templates/canteen/meal_type/list.html +1 -1
- fnschoo1/fnprofile/__init__.py +0 -0
- fnschoo1/fnprofile/admin.py +27 -0
- fnschoo1/fnprofile/apps.py +12 -0
- fnschoo1/fnprofile/forms.py +73 -0
- fnschoo1/fnprofile/migrations/0001_initial.py +213 -0
- fnschoo1/fnprofile/migrations/0002_auto_20251026_2235.py +42 -0
- fnschoo1/fnprofile/migrations/0003_alter_fnuser_options_alter_fnuser_groups_and_more.py +45 -0
- fnschoo1/fnprofile/migrations/__init__.py +0 -0
- fnschoo1/fnprofile/models.py +90 -0
- fnschoo1/fnprofile/signals.py +20 -0
- fnschoo1/fnprofile/templates/fnprofile/create.html +18 -0
- fnschoo1/fnprofile/templates/fnprofile/detail.html +16 -0
- fnschoo1/fnprofile/templates/fnprofile/edit.html +16 -0
- fnschoo1/fnprofile/templates/fnprofile/log_in.html +22 -0
- fnschoo1/fnprofile/templates/fnprofile/log_out.html +12 -0
- fnschoo1/fnprofile/tests.py +3 -0
- fnschoo1/fnprofile/urls.py +15 -0
- fnschoo1/fnprofile/views.py +69 -0
- fnschoo1/fnschool/settings.py +5 -3
- fnschoo1/fnschool/urls.py +7 -2
- fnschoo1/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- fnschoo1/profiles/__init__.py +7 -0
- fnschoo1/profiles/forms.py +6 -0
- fnschoo1/profiles/migrations/0006_profile_created_at_profile_updated_at.py +27 -0
- fnschoo1/profiles/migrations/0007_alter_profile_created_at.py +20 -0
- fnschoo1/profiles/migrations/0008_alter_profile_groups_alter_profile_user_permissions.py +38 -0
- fnschoo1/profiles/models.py +32 -2
- fnschoo1/profiles/templates/profiles/create.html +1 -1
- fnschoo1/profiles/templates/profiles/detail.html +1 -1
- fnschoo1/profiles/templates/profiles/edit.html +4 -2
- fnschoo1/profiles/templates/profiles/log_in.html +1 -1
- fnschoo1/profiles/templates/profiles/log_out.html +1 -1
- fnschoo1/profiles/views.py +7 -1
- fnschoo1/static/css/fnschool.css +14 -0
- fnschoo1/static/js/fnschool.js +20 -0
- fnschoo1/templates/home.html +1 -1
- fnschoo1/templates/includes/_header.html +30 -6
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/METADATA +1 -1
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/RECORD +58 -35
- /fnschoo1/templates/base/{header_content_footer.html → document.html} +0 -0
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/SOURCES.txt.py +0 -0
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/WHEEL +0 -0
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/dependency_links.txt.py +0 -0
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/entry_points.txt +0 -0
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/entry_points.txt.py +0 -0
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/licenses/LICENSE +0 -0
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/requires.txt.py +0 -0
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/top_level.txt +0 -0
- {fnschool-20251021.80058.842.dist-info → fnschool-20251027.82134.859.dist-info}/top_level.txt.py +0 -0
fnschoo1/__init__.py
CHANGED
fnschoo1/canteen/forms.py
CHANGED
|
@@ -20,7 +20,7 @@ class IngredientForm(forms.ModelForm):
|
|
|
20
20
|
fields = [
|
|
21
21
|
f.name
|
|
22
22
|
for f in Ingredient._meta.fields
|
|
23
|
-
if f.name not in ["id", "user", "updated_at"]
|
|
23
|
+
if f.name not in ["id", "user", "updated_at", "created_at"]
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
current_year = date.today().year
|
|
@@ -55,7 +55,7 @@ class ConsumptionForm(forms.ModelForm):
|
|
|
55
55
|
widgets = {
|
|
56
56
|
"amount_used": forms.NumberInput(
|
|
57
57
|
attrs={
|
|
58
|
-
"style": "width:
|
|
58
|
+
"style": "width: 95px; text-align: center; font-family: Mono;"
|
|
59
59
|
}
|
|
60
60
|
),
|
|
61
61
|
"date_of_using": forms.HiddenInput(),
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Generated by Django 4.2.25 on 2025-10-24 01:44
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("canteen", "0018_alter_ingredient_updated_at"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="category",
|
|
15
|
+
name="updated_at",
|
|
16
|
+
field=models.DateTimeField(
|
|
17
|
+
auto_now=True, null=True, verbose_name="更新时间"
|
|
18
|
+
),
|
|
19
|
+
),
|
|
20
|
+
migrations.AddField(
|
|
21
|
+
model_name="ingredient",
|
|
22
|
+
name="created_at",
|
|
23
|
+
field=models.DateTimeField(
|
|
24
|
+
auto_now_add=True, null=True, verbose_name="Time of creating"
|
|
25
|
+
),
|
|
26
|
+
),
|
|
27
|
+
migrations.AddField(
|
|
28
|
+
model_name="mealtype",
|
|
29
|
+
name="updated_at",
|
|
30
|
+
field=models.DateTimeField(
|
|
31
|
+
auto_now=True, null=True, verbose_name="更新时间"
|
|
32
|
+
),
|
|
33
|
+
),
|
|
34
|
+
migrations.AlterField(
|
|
35
|
+
model_name="category",
|
|
36
|
+
name="created_at",
|
|
37
|
+
field=models.DateTimeField(
|
|
38
|
+
auto_now_add=True, null=True, verbose_name="创建日期"
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
migrations.AlterField(
|
|
42
|
+
model_name="mealtype",
|
|
43
|
+
name="created_at",
|
|
44
|
+
field=models.DateTimeField(
|
|
45
|
+
auto_now_add=True, null=True, verbose_name="创建日期"
|
|
46
|
+
),
|
|
47
|
+
),
|
|
48
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Generated by Django 4.2.25 on 2025-10-24 15:20
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("canteen", "0019_category_updated_at_ingredient_created_at_and_more"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name="ingredient",
|
|
15
|
+
name="created_at",
|
|
16
|
+
field=models.DateTimeField(
|
|
17
|
+
auto_now_add=True, null=True, verbose_name="创建时间"
|
|
18
|
+
),
|
|
19
|
+
),
|
|
20
|
+
]
|
fnschoo1/canteen/models.py
CHANGED
|
@@ -22,8 +22,15 @@ class MealType(models.Model):
|
|
|
22
22
|
null=True, blank=True, max_length=100, verbose_name=_("Abbreviation")
|
|
23
23
|
)
|
|
24
24
|
created_at = models.DateTimeField(
|
|
25
|
-
null=True,
|
|
25
|
+
null=True,
|
|
26
|
+
blank=True,
|
|
27
|
+
auto_now_add=True,
|
|
28
|
+
verbose_name=_("Creating Date"),
|
|
29
|
+
)
|
|
30
|
+
updated_at = models.DateTimeField(
|
|
31
|
+
null=True, blank=True, auto_now=True, verbose_name=_("Time of updating")
|
|
26
32
|
)
|
|
33
|
+
|
|
27
34
|
is_disabled = models.BooleanField(
|
|
28
35
|
default=False, verbose_name=_("Is Disabled")
|
|
29
36
|
)
|
|
@@ -44,8 +51,12 @@ class Category(models.Model):
|
|
|
44
51
|
null=True, blank=True, max_length=100, verbose_name=_("abbreviation")
|
|
45
52
|
)
|
|
46
53
|
created_at = models.DateTimeField(
|
|
47
|
-
null=True, verbose_name=_("Creating Date")
|
|
54
|
+
null=True, auto_now_add=True, verbose_name=_("Creating Date")
|
|
55
|
+
)
|
|
56
|
+
updated_at = models.DateTimeField(
|
|
57
|
+
null=True, blank=True, auto_now=True, verbose_name=_("Time of updating")
|
|
48
58
|
)
|
|
59
|
+
|
|
49
60
|
is_disabled = models.BooleanField(
|
|
50
61
|
default=False, verbose_name=_("Is Disabled")
|
|
51
62
|
)
|
|
@@ -78,9 +89,18 @@ class Ingredient(models.Model):
|
|
|
78
89
|
verbose_name=_("User"),
|
|
79
90
|
)
|
|
80
91
|
storage_date = models.DateField(verbose_name=_("Storage Date"))
|
|
92
|
+
|
|
93
|
+
created_at = models.DateTimeField(
|
|
94
|
+
null=True,
|
|
95
|
+
blank=True,
|
|
96
|
+
auto_now_add=True,
|
|
97
|
+
verbose_name=_("Time of creating"),
|
|
98
|
+
)
|
|
99
|
+
|
|
81
100
|
updated_at = models.DateTimeField(
|
|
82
|
-
null=True, auto_now=True, verbose_name=_("Time of updating")
|
|
101
|
+
null=True, blank=True, auto_now=True, verbose_name=_("Time of updating")
|
|
83
102
|
)
|
|
103
|
+
|
|
84
104
|
name = models.CharField(max_length=100, verbose_name=_("Ingredient Name"))
|
|
85
105
|
meal_type = models.ForeignKey(
|
|
86
106
|
MealType,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{% extends "base/
|
|
1
|
+
{% extends "base/document.html" %}
|
|
2
2
|
{% load crispy_forms_tags %}
|
|
3
3
|
{% block title %}
|
|
4
4
|
{% trans "Consume Ingredients" %}
|
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
target="canteen_list_categories"
|
|
23
23
|
href="{% url "canteen:list_categories" %}">{% trans "Ingredient Categories" %}</a>
|
|
24
24
|
|
|
25
|
+
<a class="btn btn-primary col-md-1 col-lg-1 col-2 "
|
|
26
|
+
target="canteen_list_meal_types"
|
|
27
|
+
href="{% url "canteen:list_meal_types" %}">{% trans "Ingredient Meal Types" %}</a>
|
|
28
|
+
|
|
29
|
+
|
|
25
30
|
<div class="col col-3 col-md-2 col-lg-2">
|
|
26
31
|
<input class=" form-control"
|
|
27
32
|
onkeydown="if(event.keyCode==13){list_consumptions();}"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{% extends "base/
|
|
1
|
+
{% extends "base/document.html" %}
|
|
2
2
|
{% load tz %}
|
|
3
3
|
{% load crispy_forms_tags %}
|
|
4
4
|
{% block title %}
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
</div>
|
|
113
113
|
{% include 'includes/_paginator.html' %}
|
|
114
114
|
<script>
|
|
115
|
-
|
|
115
|
+
function set_ingredient_table_height() {
|
|
116
116
|
var ingredient_table = $('.table-ingredient')
|
|
117
117
|
var pagination = $('.pagination')
|
|
118
118
|
var footer = $("footer")
|
|
@@ -120,7 +120,16 @@
|
|
|
120
120
|
ingredient_table.parent().height(
|
|
121
121
|
height
|
|
122
122
|
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
$(document).ready(function() {
|
|
126
|
+
set_ingredient_table_height();
|
|
123
127
|
});
|
|
128
|
+
|
|
129
|
+
$(window).resize(function() {
|
|
130
|
+
set_ingredient_table_height();
|
|
131
|
+
});
|
|
132
|
+
|
|
124
133
|
$(document).ready(
|
|
125
134
|
function() {
|
|
126
135
|
make_highlight(".tr-ingredient", "ingredient_updated_at")
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from django.contrib import admin
|
|
2
|
+
|
|
3
|
+
from .models import Fnuser
|
|
4
|
+
|
|
5
|
+
# Register your models here.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@admin.register(Fnuser)
|
|
9
|
+
class FnuserAdmin(admin.ModelAdmin):
|
|
10
|
+
list_display = [
|
|
11
|
+
"user",
|
|
12
|
+
"phone",
|
|
13
|
+
"affiliation",
|
|
14
|
+
"superior_department",
|
|
15
|
+
"date_of_birth",
|
|
16
|
+
"address",
|
|
17
|
+
]
|
|
18
|
+
search_fields = ["user__username", "phone", "address"]
|
|
19
|
+
list_filter = ["date_of_birth"]
|
|
20
|
+
|
|
21
|
+
def user(self, obj):
|
|
22
|
+
if obj:
|
|
23
|
+
return obj.username
|
|
24
|
+
return "No User"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# The end.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
|
|
3
|
+
from django import forms
|
|
4
|
+
from django.contrib.auth.forms import AuthenticationForm
|
|
5
|
+
from django.forms import ModelForm
|
|
6
|
+
from fnschool import _
|
|
7
|
+
|
|
8
|
+
from .models import Fnuser
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FnuserLoginForm(AuthenticationForm):
|
|
12
|
+
username = forms.CharField(
|
|
13
|
+
label=_("User Name"),
|
|
14
|
+
widget=forms.TextInput(attrs={"placeholder": _("User Name")}),
|
|
15
|
+
)
|
|
16
|
+
password = forms.CharField(
|
|
17
|
+
label=_("Password"),
|
|
18
|
+
widget=forms.PasswordInput(attrs={"placeholder": _("Password")}),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class FnuserForm(ModelForm):
|
|
23
|
+
username = forms.CharField(
|
|
24
|
+
max_length=128,
|
|
25
|
+
label=_("User Name"),
|
|
26
|
+
widget=forms.TextInput(attrs={"placeholder": _("User Name")}),
|
|
27
|
+
)
|
|
28
|
+
password = forms.CharField(
|
|
29
|
+
label=_("Password"),
|
|
30
|
+
widget=forms.PasswordInput(attrs={"placeholder": _("Password")}),
|
|
31
|
+
)
|
|
32
|
+
password_confirm = forms.CharField(
|
|
33
|
+
label=_("Confirm Password"),
|
|
34
|
+
widget=forms.PasswordInput(
|
|
35
|
+
attrs={"placeholder": _("Confirm Password")}
|
|
36
|
+
),
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def __init__(self, *args, **kwargs):
|
|
40
|
+
super().__init__(*args, **kwargs)
|
|
41
|
+
self.fields["avatar"].widget.attrs.update(
|
|
42
|
+
{"class": "form-control-file"}
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
class Meta:
|
|
46
|
+
current_year = date.today().year
|
|
47
|
+
year_range = list(range(current_year - 100, current_year + 1))
|
|
48
|
+
model = Fnuser
|
|
49
|
+
fields = [
|
|
50
|
+
"username",
|
|
51
|
+
"phone",
|
|
52
|
+
"affiliation",
|
|
53
|
+
"superior_department",
|
|
54
|
+
"date_of_birth",
|
|
55
|
+
"gender",
|
|
56
|
+
"address",
|
|
57
|
+
"avatar",
|
|
58
|
+
"bio",
|
|
59
|
+
]
|
|
60
|
+
widgets = {
|
|
61
|
+
"date_of_birth": forms.SelectDateWidget(
|
|
62
|
+
years=year_range,
|
|
63
|
+
attrs={"style": "width: 33.33%; display: inline-block;"},
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
def clean(self):
|
|
68
|
+
cleaned_data = super().clean()
|
|
69
|
+
if cleaned_data.get("password") != cleaned_data.get("password_confirm"):
|
|
70
|
+
raise forms.ValidationError("Passwords do not match")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# The end.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Generated by Django 4.2.25 on 2025-10-27 13:10
|
|
2
|
+
|
|
3
|
+
import django.contrib.auth.models
|
|
4
|
+
import django.contrib.auth.validators
|
|
5
|
+
import django.utils.timezone
|
|
6
|
+
from django.db import migrations, models
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Migration(migrations.Migration):
|
|
10
|
+
|
|
11
|
+
initial = True
|
|
12
|
+
|
|
13
|
+
dependencies = [
|
|
14
|
+
("auth", "0012_alter_user_first_name_max_length"),
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
operations = [
|
|
18
|
+
migrations.CreateModel(
|
|
19
|
+
name="Fnuser",
|
|
20
|
+
fields=[
|
|
21
|
+
(
|
|
22
|
+
"id",
|
|
23
|
+
models.BigAutoField(
|
|
24
|
+
auto_created=True,
|
|
25
|
+
primary_key=True,
|
|
26
|
+
serialize=False,
|
|
27
|
+
verbose_name="ID",
|
|
28
|
+
),
|
|
29
|
+
),
|
|
30
|
+
(
|
|
31
|
+
"password",
|
|
32
|
+
models.CharField(max_length=128, verbose_name="password"),
|
|
33
|
+
),
|
|
34
|
+
(
|
|
35
|
+
"last_login",
|
|
36
|
+
models.DateTimeField(
|
|
37
|
+
blank=True, null=True, verbose_name="last login"
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
(
|
|
41
|
+
"is_superuser",
|
|
42
|
+
models.BooleanField(
|
|
43
|
+
default=False,
|
|
44
|
+
help_text="Designates that this user has all permissions without explicitly assigning them.",
|
|
45
|
+
verbose_name="superuser status",
|
|
46
|
+
),
|
|
47
|
+
),
|
|
48
|
+
(
|
|
49
|
+
"username",
|
|
50
|
+
models.CharField(
|
|
51
|
+
error_messages={
|
|
52
|
+
"unique": "A user with that username already exists."
|
|
53
|
+
},
|
|
54
|
+
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
|
|
55
|
+
max_length=150,
|
|
56
|
+
unique=True,
|
|
57
|
+
validators=[
|
|
58
|
+
django.contrib.auth.validators.UnicodeUsernameValidator()
|
|
59
|
+
],
|
|
60
|
+
verbose_name="username",
|
|
61
|
+
),
|
|
62
|
+
),
|
|
63
|
+
(
|
|
64
|
+
"first_name",
|
|
65
|
+
models.CharField(
|
|
66
|
+
blank=True, max_length=150, verbose_name="first name"
|
|
67
|
+
),
|
|
68
|
+
),
|
|
69
|
+
(
|
|
70
|
+
"last_name",
|
|
71
|
+
models.CharField(
|
|
72
|
+
blank=True, max_length=150, verbose_name="last name"
|
|
73
|
+
),
|
|
74
|
+
),
|
|
75
|
+
(
|
|
76
|
+
"email",
|
|
77
|
+
models.EmailField(
|
|
78
|
+
blank=True, max_length=254, verbose_name="email address"
|
|
79
|
+
),
|
|
80
|
+
),
|
|
81
|
+
(
|
|
82
|
+
"is_staff",
|
|
83
|
+
models.BooleanField(
|
|
84
|
+
default=False,
|
|
85
|
+
help_text="Designates whether the user can log into this admin site.",
|
|
86
|
+
verbose_name="staff status",
|
|
87
|
+
),
|
|
88
|
+
),
|
|
89
|
+
(
|
|
90
|
+
"is_active",
|
|
91
|
+
models.BooleanField(
|
|
92
|
+
default=True,
|
|
93
|
+
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
|
|
94
|
+
verbose_name="active",
|
|
95
|
+
),
|
|
96
|
+
),
|
|
97
|
+
(
|
|
98
|
+
"date_joined",
|
|
99
|
+
models.DateTimeField(
|
|
100
|
+
default=django.utils.timezone.now,
|
|
101
|
+
verbose_name="date joined",
|
|
102
|
+
),
|
|
103
|
+
),
|
|
104
|
+
(
|
|
105
|
+
"phone",
|
|
106
|
+
models.CharField(
|
|
107
|
+
blank=True,
|
|
108
|
+
max_length=15,
|
|
109
|
+
null=True,
|
|
110
|
+
verbose_name="电话号码",
|
|
111
|
+
),
|
|
112
|
+
),
|
|
113
|
+
(
|
|
114
|
+
"affiliation",
|
|
115
|
+
models.CharField(
|
|
116
|
+
blank=True,
|
|
117
|
+
max_length=255,
|
|
118
|
+
null=True,
|
|
119
|
+
verbose_name="机构",
|
|
120
|
+
),
|
|
121
|
+
),
|
|
122
|
+
(
|
|
123
|
+
"superior_department",
|
|
124
|
+
models.CharField(
|
|
125
|
+
blank=True,
|
|
126
|
+
max_length=255,
|
|
127
|
+
null=True,
|
|
128
|
+
verbose_name="上级机构",
|
|
129
|
+
),
|
|
130
|
+
),
|
|
131
|
+
(
|
|
132
|
+
"date_of_birth",
|
|
133
|
+
models.DateField(
|
|
134
|
+
blank=True, null=True, verbose_name="生日"
|
|
135
|
+
),
|
|
136
|
+
),
|
|
137
|
+
(
|
|
138
|
+
"gender",
|
|
139
|
+
models.CharField(
|
|
140
|
+
choices=[("M", "男"), ("F", "女"), ("U", "--")],
|
|
141
|
+
default="U",
|
|
142
|
+
max_length=1,
|
|
143
|
+
verbose_name="性别",
|
|
144
|
+
),
|
|
145
|
+
),
|
|
146
|
+
(
|
|
147
|
+
"address",
|
|
148
|
+
models.CharField(
|
|
149
|
+
blank=True,
|
|
150
|
+
max_length=255,
|
|
151
|
+
null=True,
|
|
152
|
+
verbose_name="地址",
|
|
153
|
+
),
|
|
154
|
+
),
|
|
155
|
+
(
|
|
156
|
+
"avatar",
|
|
157
|
+
models.ImageField(
|
|
158
|
+
blank=True,
|
|
159
|
+
null=True,
|
|
160
|
+
upload_to="avatars/",
|
|
161
|
+
verbose_name="头像",
|
|
162
|
+
),
|
|
163
|
+
),
|
|
164
|
+
(
|
|
165
|
+
"bio",
|
|
166
|
+
models.TextField(
|
|
167
|
+
blank=True, max_length=512, verbose_name="个人简介"
|
|
168
|
+
),
|
|
169
|
+
),
|
|
170
|
+
(
|
|
171
|
+
"created_at",
|
|
172
|
+
models.DateTimeField(
|
|
173
|
+
auto_now_add=True, null=True, verbose_name="创建时间"
|
|
174
|
+
),
|
|
175
|
+
),
|
|
176
|
+
(
|
|
177
|
+
"updated_at",
|
|
178
|
+
models.DateTimeField(
|
|
179
|
+
auto_now=True, null=True, verbose_name="更新时间"
|
|
180
|
+
),
|
|
181
|
+
),
|
|
182
|
+
(
|
|
183
|
+
"groups",
|
|
184
|
+
models.ManyToManyField(
|
|
185
|
+
blank=True,
|
|
186
|
+
help_text="The groups this user belongs to.",
|
|
187
|
+
related_name="fn_user_groups",
|
|
188
|
+
related_query_name="fn_user",
|
|
189
|
+
to="auth.group",
|
|
190
|
+
verbose_name="groups",
|
|
191
|
+
),
|
|
192
|
+
),
|
|
193
|
+
(
|
|
194
|
+
"user_permissions",
|
|
195
|
+
models.ManyToManyField(
|
|
196
|
+
blank=True,
|
|
197
|
+
help_text="这个用户的特定权限。",
|
|
198
|
+
related_name="fn_user_permissions",
|
|
199
|
+
related_query_name="fn_user",
|
|
200
|
+
to="auth.permission",
|
|
201
|
+
verbose_name="user permissions",
|
|
202
|
+
),
|
|
203
|
+
),
|
|
204
|
+
],
|
|
205
|
+
options={
|
|
206
|
+
"verbose_name": "User Information",
|
|
207
|
+
"verbose_name_plural": "User Information",
|
|
208
|
+
},
|
|
209
|
+
managers=[
|
|
210
|
+
("objects", django.contrib.auth.models.UserManager()),
|
|
211
|
+
],
|
|
212
|
+
),
|
|
213
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Generated by Django 4.2.25 on 2025-10-26 14:35
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def migrate_data_forward(apps, schema_editor):
|
|
7
|
+
profiles_profile_model = apps.get_model("profiles", "Profile")
|
|
8
|
+
fnprofile_fnuser_model = apps.get_model("fnprofile", "Fnuser")
|
|
9
|
+
|
|
10
|
+
for profile in profiles_profile_model.objects.all():
|
|
11
|
+
fnprofile_fnuser_model.objects.create(
|
|
12
|
+
phone=profile.phone,
|
|
13
|
+
affiliation=profile.affiliation,
|
|
14
|
+
superior_department=profile.superior_department,
|
|
15
|
+
date_of_birth=profile.date_of_birth,
|
|
16
|
+
gender=profile.gender,
|
|
17
|
+
address=profile.address,
|
|
18
|
+
avatar=profile.avatar,
|
|
19
|
+
bio=profile.bio,
|
|
20
|
+
password=profile.password,
|
|
21
|
+
username=profile.username,
|
|
22
|
+
id=profile.id,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def migrate_data_backward(apps, schema_editor):
|
|
27
|
+
fnprofile_fnuser_model = apps.get_model("fnprofile", "Fnuser")
|
|
28
|
+
fnprofile_fnuser_model.objects.all().delete()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Migration(migrations.Migration):
|
|
32
|
+
|
|
33
|
+
dependencies = [
|
|
34
|
+
("fnprofile", "0001_initial"),
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
operations = [
|
|
38
|
+
migrations.RunPython(
|
|
39
|
+
code=migrate_data_forward,
|
|
40
|
+
reverse_code=migrate_data_backward,
|
|
41
|
+
),
|
|
42
|
+
]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Generated by Django 4.2.25 on 2025-10-27 13:34
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("auth", "0012_alter_user_first_name_max_length"),
|
|
10
|
+
("fnprofile", "0002_auto_20251026_2235"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterModelOptions(
|
|
15
|
+
name="fnuser",
|
|
16
|
+
options={
|
|
17
|
+
"verbose_name": "用户信息",
|
|
18
|
+
"verbose_name_plural": "用户信息",
|
|
19
|
+
},
|
|
20
|
+
),
|
|
21
|
+
migrations.AlterField(
|
|
22
|
+
model_name="fnuser",
|
|
23
|
+
name="groups",
|
|
24
|
+
field=models.ManyToManyField(
|
|
25
|
+
blank=True,
|
|
26
|
+
help_text="这个用户所属的组。",
|
|
27
|
+
related_name="fn_user_groups",
|
|
28
|
+
related_query_name="fn_user",
|
|
29
|
+
to="auth.group",
|
|
30
|
+
verbose_name="groups",
|
|
31
|
+
),
|
|
32
|
+
),
|
|
33
|
+
migrations.AlterField(
|
|
34
|
+
model_name="fnuser",
|
|
35
|
+
name="user_permissions",
|
|
36
|
+
field=models.ManyToManyField(
|
|
37
|
+
blank=True,
|
|
38
|
+
help_text="给这个用户指定权限。",
|
|
39
|
+
related_name="fn_user_permissions",
|
|
40
|
+
related_query_name="fn_user",
|
|
41
|
+
to="auth.permission",
|
|
42
|
+
verbose_name="user permissions",
|
|
43
|
+
),
|
|
44
|
+
),
|
|
45
|
+
]
|
|
File without changes
|