it-swarm-pt.tech

Django: como verificar se o nome de usuário já existe

eu não sou um usuário muito avançado do Django. Eu já vi muitos métodos diferentes online, mas todos são para modelos modificados ou muito complicados para eu entender. Estou reutilizando o UserCreationForm no meu MyRegistrationForm

class MyRegistrationForm(UserCreationForm):

    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')

    def save(self, commit=True):
        user = super(MyRegistrationForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        user.set_password(self.cleaned_data["password1"])

        if commit:
            user.save()

        return user

Eu luto para entender ou encontrar uma maneira de verificar se o nome de usuário digitado pelo usuário já está sendo usado ou não. Então, eu apenas uso isso para me redirecionar para html, onde diz nome de usuário ou senhas ruins não coincidem:

def register_user(request):
    if request.method == 'POST':
        form = MyRegistrationForm(request.POST)
        if form.is_valid():
            form.save()

            return HttpResponseRedirect('/accounts/register_success')
        else:
            return render_to_response('invalid_reg.html')


    args = {}
    args.update(csrf(request))

    args['form'] = MyRegistrationForm()
    print args
    return render_to_response('register.html', args)

Aqui está o meu modelo de registro (se necessário):

{% extends "base.html" %}

{% block content %}

<section>
<h2 style="text-align: center">Register</h2>
<form action="/accounts/register/" method="post">{% csrf_token %}

<ul>
{{form.as_ul}}
</ul>
<input type="submit" value="Register" onclick="validateForm()"/>

</form>

</section>
{% endblock %}

Mas eu preciso criar algum tipo de exceção ou algo parecido antes que o usuário seja redirecionado. Talvez quando o usuário pressionar registrar, ele/ela receberia o erro/garantia dizendo que o nome de usuário já foi usado? Isso é possível?

12
pptt

Você pode usar existe :

from Django.contrib.auth.models import User

if User.objects.filter(username=self.cleaned_data['username']).exists():
    # Username exists
    ...
19
JuniorCompressor

Você pode verificar se o username existe com o método clean_username E aumentar ValidationError :

def clean_username(self, username):
    user_model = get_user_model() # your way of getting the User
    try:
        user_model.objects.get(username__iexact=username)
    except user_model.DoesNotExist:
        return username
    raise forms.ValidationError(_("This username has already existed."))

Nesse caso, você pode mostrar o erro no formulário de inscrição e não precisa redirecionar para outra página.

atualizar:

Conforme @Spacedman apontou um ponto válido em relação às condições de corrida na verificação da exclusividade do nome de usuário na lógica do formulário em relação ao nível do banco de dados, embora sua chance de obter isso seja muito improvável, caso você faça aqui as respostas SO relevantes que podem Vale a pena ler:

Como evitar a condição de corrida com verificações exclusivas no Django

Condições da corrida no Django

Outra atualização

De acordo com o comentário do OP, aqui está outra alteração que pode ser feita nas visualizações:

def register_user(request):
    # be DRY, the form can be reused for both POST and GET
    form = MyRegistrationForm(request.POST or None)

    # check both request is a POST and the form is valid
    # as you don't need to redirect for form errors, remove else block
    # otherwise it's going to redirect even form validation fails
    if request.method == 'POST' and form.is_valid():
        form.save()
        return HttpResponseRedirect('/accounts/register_success')
    # I use render so need not update the RequestContext, Django does it for you
    html = render(request, 'register.html', {'form': form})
    return HttpResponse(html)

Espero que isto ajude.

5
Anzel