Web3 backend and smart contract development for Python developers Musical NFTs part 9: Django backend (register new user)
Tags: python, django, ethereum, nft
Published: 2023-10-07 18:23:49

Now it is time to add sign-up functionality to our app. For this to happen add to app `authentication` `urls.py` additonal path

  

```
  from django.urls import path

    from .views import HomeView, LogoutUser, RegisterUser

    urlpatterns = [
        path("", HomeView.as_view(), name="home"),
        # path("login/", LoginUser.as_view(), name="login"),
        path("logout/", LogoutUser.as_view(), name="logout"),
        # This is new path for registration process 
        path("register/", RegisterUser.as_view(), name="register"),

    ]
```

Let's define `SignUpForm` class inside our `forms.py` (`authentication` app folder). This `SignUpFrom` will mainly handle all things related to new users. More details in comments of the code inside `forms.py`

    

```
from django.contrib.auth.forms import UserCreationForm   
    from django.contrib.auth.models import User
    from django import forms 



    class SignUpForm(UserCreationForm):
        # Here widget means form field that show up to user it is text field, text for placeholder 
        # EmailField will make basic validation if email have @ etc.
        # max_length is number of characters this field allow
        # Here we are defining 3 fields from User model
        email = forms.EmailField(label="", widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Email address'}), required=True)
        first_name = forms.CharField(label="", widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'First name'}), max_length=100, required=True)
        last_name =  forms.CharField(label="", widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Last name'}), max_length=100, required=True)

        class Meta:
            # Django User model will be used to write to database
            model = User
            # 
            fields = [
                "username", "first_name", "last_name", "email", "password1", "password2",
            ]

        def __init__(self, *args, **kwargs):
            super(SignUpForm, self).__init__(*args, **kwargs)
            # Here we are defining 3 new addtional fields: username, password1 and password2. 
            # Reason why we have two passwords in place it's because we need to confirm that first entry was corrrect
            self.fields['username'].widget.attrs['class'] = 'form-control'
            self.fields['username'].widget.attrs['placeholder'] = 'User Name'
            self.fields['username'].label = ''
            self.fields['username'].help_text = '<span class="form-text text-muted"><small>Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.</small></span>'

            self.fields['password1'].widget.attrs['class'] = 'form-control'
            self.fields['password1'].widget.attrs['placeholder'] = 'Password'
            self.fields['password1'].label = ''
            self.fields['password1'].help_text = '<ul class="form-text text-muted small"><li>Your password can\'t be too similar to your other personal information.</li><li>Your password must contain at least 8 characters.</li><li>Your password can\'t be a commonly used password.</li><li>Your password can\'t be entirely numeric.</li></ul>'

            self.fields['password2'].widget.attrs['class'] = 'form-control'
            self.fields['password2'].widget.attrs['placeholder'] = 'Confirm Password'
            self.fields['password2'].label = ''
            self.fields['password2'].help_text = '<span class="form-text text-muted"><small>Enter the same password as before, for verification.</small></span>'	

```

In `authentication` app `view.py` add new class to handle this registration process (more details on what code do again you can found in code comments)

    

```
class RegisterUser(TemplateView):
        
        def post(self, request): 
            # Everything what user post (means submit the forms with his detils) will be handled with this post method 
            form = SignUpForm(request.POST)
            if form.is_valid():
                form.save()
                # Authenticate use and login
                username = form.cleaned_data['username']
                password = form.cleaned_data['password1']
                user = authenticate(username=username, password=password)
                login(request, user)
                messages.success(request,  "You have been sucesfuly logged in ")
                return redirect("home")
            return render(request, "register.html", {"form": form}) 

        def get(self, request):
            form = SignUpForm()
            return render(request, "register.html", {"form": form}) 

```

Then in global `templates` create new  `register.html` to be used inside our `view.py`

    

```
{% extends 'base.html'%}

    {% block content%}

    <div class="col-md-6 offset-md-3"> 
    <h1> Register  </h1>
    <br>

    <form method="POST" action=""> 
        {% csrf_token %}
        {% if form.errors %}
                <div class="alert alert-warning alert-dismissible fade show" role="alert">
                Your Form Has Errors
                {% for field in form %}
                    {% if field.errors %}
                        {{ field.errors }}
                    {% endif %}
                {% endfor %}
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
            {% endif %}

        {{ form.as_p }}
        <br>
        <button type="submit" class="btn btn-secondary">Register</button>
    </form>
    </div>
    {% endblock %}
```


Then updatet existing `navbar.html` template with link for `register.html`.

       

```
 <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container-fluid">
        <a class="navbar-brand" href="{% url 'home' %}">Musical NFT </a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">

            {% if user.is_authenticated%}
            <li class="nav-item">
            <a class="nav-link" href="{% url 'logout'%}">Logout</a>
            </li>
            
            {% else %}
            <li class="nav-item">
            <a class="nav-link" href="{% url 'register'%}">Register</a>
            </li>
            <li class="nav-item">
            <a class="nav-link" href="{% url 'home'%}">Login</a>
            </li>
            {% endif%}
                </ul>
            </li>
            </ul>
        </div>
        </div>
    </nav>
```

And basically this is it. With this we create new `forms.py` which handle relation to our user database model as well as forms user see on sign-up page (through instantiation of `SignUpForm` class inside our `views.py` and using `render()` function to pass it like context to our `register.html` template). And this is main pattern that we have here `forms.py` is kind of bridge between database and front-end. If everything went well on page `http://127.0.0.1:8000/register/`you should see something like this


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/559yis82srirn0l8guq0.png)

Ones you enter new user data he will be able to login to his profile and in the same time you can find him in admin dashboard under `users` (or from Django shell by importing `User` model and then querying database for that concrete user)

Link to github [repo](https://github.com/ilijapet/musical_nft_thumbnails)