2017-10-18 3 views
0

J'écris un UpdateView UpdateAccountView pour le modèle User, mise à jour par un ModelForm MyUserCreationForm qui est déjà le ModelForm utilisé pour créer de nouveaux utilisateurs. Le problème est que chaque fois que je clique sur Envoyer pour enregistrer les modifications dans le modèle, le modèle est redélivré. Par exemple, si je n'ai pas changé de champs, cela me donne l'erreur de "Nom d'utilisateur déjà pris" que je vais vous montrer dans le MyUserCreationForm pour vérifier les noms d'utilisateur uniques, ou juste rediffuser le modèle pour les nouvelles entrées sur les champs, sans réellement enregistrer les modifications apportées au modèle.Django UpdateView pas enregistrer si nouvel utilisateur ou utilisateur existant utilisant ModelForm

Voici mon MyUserCreationForm

class MyUserCreationForm(UserCreationForm): 

    class Meta: 
     model = User #extended from auth.models.User 
     fields = ("first_name", "last_name", "username", "email", "gender", "profile_photo") 

    # adding bootstrap styling to the ModelForm fields 
    def __init__(self, *args, **kwargs): 
     super(MyUserCreationForm, self).__init__(*args, **kwargs) 
     for field in iter(self.fields): 
      self.fields[field].widget.attrs.update({ 
       'class': 'form-control input-lg', 
       'placeholder': field.replace("_", " ").title(), 
       'tabindex': list(self.fields).index(field) + 1}) 
      self.fields[field].widget.attrs.pop('autofocus', None) 

      if field == 'username' or field == 'email': 
       self.fields[field].widget.attrs.update({ 
        'placeholder': field.replace("_", " ").title() + ' *', 
       }) 


    def clean_username(self): 

     username = self.cleaned_data['username'] 
     if not re.search(r'^[\w.-]+$', username): 
      raise forms.ValidationError('Username can only contain alphanumeric characters, dots, hyphens ,and underscores') 
     try: 
      User.objects.get(username=username) 
     except ObjectDoesNotExist: 
      return username 
     raise forms.ValidationError('Username is already taken.') 

et voici la classe de vue UpdateAccountView

class UpdateAccountView(UpdateView): 
    form_class = MyUserCreationForm 
    model = User 
    template_name = 'auth/account-edit.html' 
    success_url = '/' 

    def get_object(self, queryset=None): 
     return self.request.user 

Cependant, si je mets à jour directement le modèle en utilisant le modèle et les champs dans le UpdateView, il fonctionne bien. Mais je dois le faire à travers le ModelForm pour avoir le contrôle sur les styles lors du rendu. Donc, je sais que le problème se situe dans ModelForm mais je ne le trouve pas, même après avoir beaucoup cherché.

Merci d'avance.

+0

Cela n'a pas vraiment de sens d'utiliser un formulaire de création pour mettre à jour l'objet. En particulier, le formulaire 'UserCreation' a un code qui définit le mot de passe. ce qui peut vous causer des problèmes. Il pourrait être préférable de factoriser le code qui style le modèle dans un mixin séparé. – Alasdair

+0

Je préférerais opter pour cette option si je la connaissais. Je veux dire qu'il serait mieux pour moi de séparer le style du widget 'init' de ModelForm. Pourriez-vous s'il vous plaît me référer comment styliser le modelform dans un mixin? – Khaled

+0

Je ne peux pas - je ne sais pas ce que "un autre code" est – Alasdair

Répondre

0

Vous pouvez essayer de déplacer le code que les styles les champs à un mixin séparé:

class UserStyleMixin(object): 
    def __init__(self, *args, **kwargs): 
     super(UserStyleMixin, self).__init__(*args, **kwargs) 
     # Style the fields here 

Ensuite, vous pouvez faire votre MyUserCreationForm utiliser le mixin, et de créer une nouvelle forme pour la vue de la mise à jour.

class MyUserCreationForm(UserStyleMixin, UserCreationForm): 
    ... 

class UserUpdateForm(UserStyleMixin, forms.ModelForm): 
    ... 

Notez que si la vue de la mise à jour permet à l'utilisateur de changer le nom d'utilisateur, alors vous devriez toujours vérifier que le nom d'utilisateur est autorisé et unique. Si vous avez unique=True pour le nom d'utilisateur dans votre modèle, Django devrait prendre soin de cela pour vous. Ce serait une bonne idée de déplacer le nom d'utilisateur regex au modèle aussi bien.

+1

Très bien! Oui j'ai créé un nouveau ModelForm pour la updateview et maintenant ça fonctionne bien. J'ai aussi fait le mixin. BTW, mon modèle 'User' hérite de django' AbstractUser' qui a déjà des fonctionnalités intéressantes pour vérifier l'unicité et l'exactitude. J'ai enlevé toute la fonction 'clean_username' et j'ai laissé django s'en charger. Merci pour la réponse. – Khaled