title: Django Forms - Different Versions
body: <p>I am learning django so i looked over a tutorial and then i am looking over another one now. So  there are two versions of Signup form i came acrosss.</p>
  
  <p><strong>1st Version:</strong></p>
  
  <pre><code>from django import forms
  from django.contrib.auth.models import User
  from django.contrib.auth.forms import UserCreationForm
  
  
  class MyRegForm(UserCreationForm):
      email=forms.EmailField(required=True)
  
      class Meta:
          model = User
          fields =('username','email','password','password2')
  
      def save(self, commit=True):
          user=super(UserCreationForm,self).save(commit=False)
          if commit:
              user.save()
          return user
  </code></pre>
  
  <p>Looking at the first version i was able to understand that  i can even make a new  form by just making this simple class extending from class like this:</p>
  
  <pre><code>from django import forms
  from models import Article
  
  class ArtForm(forms.ModelForm):
  
      class Meta:
          model = Article
          fields = ('title', 'body', 'pub_data', 'thumb')
  </code></pre>
  
  <p><strong>2nd Version:</strong></p>
  
  <pre><code>from django import forms
  from django.contrib.auth.models import User
  
  class SignupForm(forms.Forms):
      username = forms.CharField(max_length=20)
      email = forms.EmailField()
      pass1 = forms.CharField(max_length=20,widget=forms.PasswordInput(render_value=False))
      pass2 = forms.CharField(max_length=20,widget=forms.PasswordInput(render_value==False))
  
      def clean_username(self):
          try:
              User.objects.get(username=self.cleaned_data['username'])
          except User.DoesNotExist:
              return self.cleaned_data['username']
          raise forms.ValidationError("The Username is already in use. Please Choose Another")
  
      def clean_pass2(self):
          if self.cleaned_data['pass2']!=self.cleaned_data['pass1']:
                raise forms.ValidationError("The two passwords should match")
          return self.cleaned_data['pass2']
  
      def save(self):
          new_user = User.objects.create_user(username=self.cleaned_data['username'],
                                              email=self.cleaned_data['email'],
                                              password=self.cleaned_data['pass1'])
          return new_user
  </code></pre>
  
  <p>In this second version we have to setup everything on our own, seems we are having a bit more power being able to add custom validation to it. The save function here seems weird , i dont see in object.save() call in it. It just returns the object. 
  So which version should be used professionally? 
  The second version does not have any Meta data in it. I think we can actually mix both kind of versions, but what is missing from both of them and which ones is more generally used?</p>