web-dev-qa-db-fra.com

Vérifier si le nom d'utilisateur existe dans Django

Je travaille sur un projet Django dans lequel les utilisateurs pourront modifier leur nom d'utilisateur avec leur prénom et leur nom de famille sous une forme. Dans forms.py, j'essaie de savoir si l'utilisateur existe. Si c'est le cas, il devrait afficher une erreur. Le problème est que si l'utilisateur veut changer son nom et son prénom et laisse son nom d'utilisateur dans l'entrée, cela déclenche une erreur de validation. De toute évidence, ce nom d'utilisateur existe déjà. Existe-t-il un moyen de vérifier s'il correspond au nom d'utilisateur de l'utilisateur actuellement connecté et d'éviter d'afficher l'erreur?

class ChangeNameForm(forms.ModelForm):
    username = forms.CharField(max_length=30)
    first_name = forms.CharField(max_length=255)
    last_name = forms.CharField(max_length=255)

    def clean_username(self):
        username = self.cleaned_data['username']

        try:
            user = User.objects.get(username=username)
        except user.DoesNotExist:
            return username
        raise forms.ValidationError(u'Username "%s" is already in use.' % username)

Je vous remercie.

13
lukas

Lorsque les ModelForms sont liés à un objet de modèle, ils ont un attribut appelé "instance", qui est l'objet de modèle lui-même. Selon vous, lorsque request.method == 'POST', vous créez probablement l'instance de formulaire de la manière suivante:

form = ChangeNameForm(request.POST, instance=request.user)

Si tel est le cas, vous pouvez accéder à l'utilisateur connecté à partir des méthodes de formulaire et votre méthode de validation peut ressembler à ceci:

def clean_username(self):
    username = self.cleaned_data['username']
    try:
        user = User.objects.exclude(pk=self.instance.pk).get(username=username)
    except User.DoesNotExist:
        return username
    raise forms.ValidationError(u'Username "%s" is already in use.' % username)

Pensez à utiliser la méthode .exists , car elle pose une requête plus rapide à votre base de données que si vous essayez de récupérer toutes les informations utilisateur avec la méthode .get . Et le code devient un peu plus propre aussi:

def clean_username(self):
    username = self.cleaned_data['username']
    if User.objects.exclude(pk=self.instance.pk).filter(username=username).exists():
        raise forms.ValidationError(u'Username "%s" is already in use.' % username)
    return username

Si vous le souhaitez, vous pouvez également suivre ces instructions lorsque vous générez ValidationError.

Je ne peux pas tester ce code pour le moment, alors je m'excuse si quelque chose ne va pas.

27
Victor Silva

Voici comment j'ai réussi à le faire fonctionner (en supposant que vous ayez un utilisateur connecté):

forms.py

from Django.contrib.auth.forms import UserChangeForm
from Django.contrib.auth.models import User

class MyUserChangeForm(UserChangeForm):
    def __init__(self, *args, **kwargs):
        super(MyUserChangeForm, self).__init__(*args, **kwargs)
        del self.fields['password']

    class Meta:
        model = User
        fields = ('username', 'first_name')

views.py

def home(request):
    if request.method == 'POST':
        form = MyUserChangeForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()
    else:
        form = MyUserChangeForm(instance=request.user)

    return render(request, 'change_user.html', {"form": form})
0
mariodev