Нахожусь ли я на правильном пути к внедрению нескольких родных и изучаемых языков в форму регистрации пользователя?
Я пытаюсь создать простую цифровую платформу для обучения, похожую на флэшкарту, где пользователь может выбрать свой родной язык и языки, которые он изучает. Как вы можете себе представить, могут быть люди, которые говорят на нескольких языках на родном уровне, и я уверен, что есть люди, которые изучают несколько языков. Чтобы обрисовать мою проблему, предположим, что пользователь изучает 20 языков и может свободно говорить на 3 языках.
В перспективе я хотел бы использовать языки пользователя (как изучаемые, так и родные) и использовать их в качестве фильтрации выпадающего списка. Например, они могут прикрепить один язык к карточке, но в выпадающем списке выбора языка будут показаны все изученные языки.
Я не совсем уверен в том, что мне следует погуглить, чтобы решить проблему выбора языка при регистрации пользователя. Я знаю, что мог бы легко решить эту проблему, жестко закодировав поля в моей модели User, но это нарушает принцип DRY и, вероятно, станет беспорядочным в обслуживании, а затем попытался решить эту проблему с помощью ArrayField, но в моей админке выбор не отображается и это просто пустое поле CharField.
(Жестко закодировано) Ужасная реализация
Я знаю, что могу реализовать это, просто перечислив кучу повторяющихся полей, а затем преобразовать CharField в поле Select через choices:
class User(AbstractUser):
native_language1 = ...
native_language2 = ...
native_language3 = ...
studying_language1 = ...
....
native_language20 = ...
Но что произойдет, если я захочу добавить или уменьшить количество разрешенных языков в каждой категории (изучаемый и родной язык)? Кажется, что такой подход вызовет много головной боли в будущем.
(Потенциальное решение) Использование ArrayField
Я просматривал документацию и нашел ArrayField
. Я подумал, что это решит мою проблему, потому что я смогу просто хранить выбранные языки в массиве. И тогда мне просто нужно будет придумать, как использовать метод clean, чтобы ограничить количество языков, которые можно выбрать для полей изучения и родного языка.
users\models.py
...
from django.contrib.postgres.fields import ArrayField
from django.conf.global_settings import LANGUAGES
class User(AbstractUser):
"""
Default custom user model for LangCorrect.
If adding fields that need to be filled at user signup,
check forms.SignupForm and forms.SocialSignupForms accordingly.
"""
#: First and last name do not cover name patterns around the globe
name = CharField(_("Name of User"), blank=True, max_length=255)
first_name = None # type: ignore
last_name = None # type: ignore
#: User languages
native_languages = ArrayField(
CharField(choices=LANGUAGES, max_length=10)
)
studying_languages = ArrayField(
CharField(choices=LANGUAGES, max_length=10)
)
def get_absolute_url(self):
"""Get url for user's detail view.
Returns:
str: URL for user detail.
"""
return reverse("users:detail", kwargs={"username": self.username})
Выбор языка не отображается и это просто пустое поле CharField.
Admin
@admin.register(User)
class UserAdmin(auth_admin.UserAdmin):
form = UserAdminChangeForm
add_form = UserAdminCreationForm
fieldsets = (
(None, {"fields": ("username", "password")}),
(_("Personal info"), {"fields": ("name", "email")}),
(
_("Languages"),
{
"fields": (
"native_languages",
)
},
),
(
_("Permissions"),
{
"fields": (
"is_active",
"is_staff",
"is_superuser",
"groups",
"user_permissions",
),
},
),
(_("Important dates"), {"fields": ("last_login", "date_joined")}),
)
list_display = ["username", "name", "is_superuser"]
search_fields = ["name"]
Так что мне интересно, на правильном ли я пути с использованием ArrayField, или я должен использовать что-то другое?