diadia

興味があることをやってみる。自分のメモを残しておきます。

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)