django Userモデルのusernameを変更させる
各ユーザーがユーザーネームを自由に変更できるようにしたい。時間がかかってしまったので記録しておく。
概要
django-allauthを使っている。ユーザー認証及び登録はemailアドレスで行っている。
そのためusernameはemailアドレスの@以前の部分が自動的に割り当てられる。当初usernameの変更のためにemailアドレスを変更する必要があるかもしれないと思っていたが、django.contrib.auth.models.Userモデルのインスタンスを直接変更すれば済む結論が得られた。
手続き
usernameを変更する際にdjango-allauthまたはビルトインのUserバリデーションを利用したいと考えた。そのためusernameの仕組みを少し調べたが詳しくはわからなかった。ただhttps://github.com/django/django/blob/master/django/contrib/auth/forms.py#L81にUserCreationFormがあり、それを参考に今回はusernameの変更を試みた。
forms.py... from django import forms from django.contrib.auth.models import User class UsernameChangeForm(forms.ModelForm): class Meta: model = User fields = ("username",) field_classes = {'username': UsernameField} def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for field in self.fields.values(): field.widget.attrs['class'] = "form-control" field.widget.attrs['placeholder'] = "150 characters or fewer. Letters, digits and @/./+/-/_ only."
views.py... from django.shortcuts import render, redirect from django.views.generic import View from django.contrib.auth.models import User from django.contrib import messages from app.forms import UsernameChangeForm class UsernameChangeView(View): def get(self, request, *args, **kwargs): context = {} form = UsernameChangeForm() context["form"] = form return render(request, 'app/change_username.html', context) def post(self, request, *args, **kwargs): context = {} form = UsernameChangeForm(request.POST) if form.is_valid(): username = form.cleaned_data["username"] user_obj = User.objects.get(username=request.user.username) user_obj.username = username user_obj.save() messages.info(request,"usernameを変更しました。") return redirect('profiles:profile') else: context["form"] = form return render(request, 'config/change_username.html', context)