Djitter - how to build a twitter clone using Django 2.0 - Part four

Djitter - how to build a twitter clone using Django 2.0 - Part four

Published 10. jun 2018 11:18 by Stein Ove Helset

In the fourth part of the series we're going make it possible to register and sign in to Djitter. So it's finally beginning to be a bit exciting!

We begin this part by setting up a form for registration and one for authorization. Create a file inside the djeeter folder.


$ touch djeeterprofile/forms.py

Open the forms.py file in your editor and write the following code.


# Import django forms and models

from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from django.contrib.auth.models import User
from django import forms
from django.utils.html import strip_tags

class SignupForm(UserCreationForm):
  email = forms.EmailField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'Email', 'class': 'form-control'}))
  first_name = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'First Name', 'class': 'form-control'}))
  last_name = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'Last Name', 'class': 'form-control'}))
  username = forms.CharField(widget=forms.widgets.TextInput(attrs={'placeholder': 'Username', 'class': 'form-control'}))
  password1 = forms.CharField(widget=forms.widgets.PasswordInput(attrs={'placeholder': 'Password', 'class': 'form-control'}))
  password2 = forms.CharField(widget=forms.widgets.PasswordInput(attrs={'placeholder': 'Password Confirmation', 'class': 'form-control'}))

  class Meta:
    fields = ['email', 'username', 'first_name', 'last_name', 'password1', 'password2']
    model = User

class SigninForm(AuthenticationForm):
  username = forms.CharField(widget=forms.widgets.TextInput(attrs={'placeholder': 'Username', 'class': 'form-control'}))
  password = forms.CharField(widget=forms.widgets.PasswordInput(attrs={'placeholder': 'Password', 'class': 'form-control'}))

If we wanted we could just use the default forms (AuthenticationForm and UserCreationForm) from Django, but we extend and change them a little bit so it's easier to view errors and we can add placeholders.

Implement the forms

Now we're going to implement those to forms and make it possible to sign in and sign up. Open up djitter/urls.py in your editor and replace the content with the following code.


from django.urls import path

from djeeterprofile.views import frontpage, signout

urlpatterns = [
  path('', frontpage, name='frontpage'),
  path('signout/', signout, name='signout'),
]

It looks like the default urls.py but we have import the index view (not created yet) from the djeeterprofile app.

Open djeeterprofile/views.py in your editor and write the following code.


# Import django and models

from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.models import User
from djeeterprofile.forms import SignupForm, SigninForm

# Views

def frontpage(request):
  if request.user.is_authenticated:
    return render(request, 'profile.html')
  else:
    if request.method == 'POST':
      if 'signupform' in request.POST:
        signupform = SignupForm(data=request.POST)
        signinform = SigninForm()
        
        if signupform.is_valid():
          username = signupform.cleaned_data['username']
          password = signupform.cleaned_data['password1']
          signupform.save()
          user = authenticate(username=username, password=password)
          login(request, user)
          return redirect('/')
      else:
        signinform = SigninForm(data=request.POST)
        signupform = SignupForm()
        
        if signinform.is_valid():
          login(request, signinform.get_user())
          return redirect('/')
    else:
      signupform = SignupForm()
      signinform = SigninForm()
  
    return render(request, 'frontpage.html', {'signupform': signupform, 'signinform': signinform})

def signout(request):
  logout(request)
  return redirect('/')

The frontpage view is where we handle sign in and sign up. Since there are two different forms on the same page we need to make sure that we are receiving the correct data. Therefor we added a name attribute to the submit buttons. The first check here pulls the data from the SignupForm and set it as it's data. Django has a built in way to check if the form is valid based on the rules we have set in forms.py

Try it!

If you want you can test the site now by running this command.


$ python manage.py runserver

If you go to your browser now and open the url http://127.0.0.1:8000 you will see our front page with the sign in and sign up forms. Let us create one more template file.


$ touch templates/profile.html

Open the file in your editor and paste the following code.


{% extends 'templates/base.html' %}

{% block main %}
{% endblock %}

Summary

If you try to sign up now and everything is OK you will be redirected back to the frontpage but user.is_authenticated will now be true and a different template(profile.html) will be rendered. Right now it's just a white page, but in the next part we will change this :-)

If you've got any questions your are more than welcome to leave a comment and I'll answer as soon as possible.

Next part

Share this post

Comments

Ruben

10. jun 2018 12:20

Good, keep 'em coming :D

Pt

10. jun 2018 19:54

Wow. Ty so much for these articles. Please keep it up.

Stein Ove Helset

10. jun 2018 21:18

@Ruben and @Pt
Thanks, part five is coming tomorrow :-) Be sure to sign up for the newsletter and you'll get a digest of what's new once a week!

martin

25. sep 2018 08:00

There's a tiny typo in the first import line of the forms.py codeblock: a sneaky angular bracket stuck itself to the end of the line:

from django.contrib.auth.forms import AuthenticationForm, UserCreationForm>

Thanks for your great tutorial : )

Stein Ove Helset

26. sep 2018 05:40

Thank you, Martin! I have remove the "<" now :-)

Add comment