Having in mind that we want user to be able to see what he own and few more details we should develop user profile page. We will have two type of users: credit card buyer (the ones who want to buy NFT with credit card). And second, crypto buyer who wants to pay his musical NFT directly in USDC (in our case MockUSDC). Part of all users profile page will be the same and part will have different elements (one with credit cards will have Stripe integration for example) and then for crypto buyers we will need direct integration to smart contract. For all this to happen we need to create one new models.py
with Customer
class. This model will be used to write in our postgres database details about user as well as to track how many NFTs he own. Then we will update get
method of our HomeView
class to return information about currently logged-in user as context to our template. Then we need to update our template home.html
where first we will check if user is crypto buyer (and offer him one type of page with crypto relevant buttons) or credit card buyer where we will offer him functionalitey they need to perform desired operations.
Now let's move first to our database. For now we should define new Customer
class model inside authenticatio/models.py
. Class can look something like this (details are explained in code comments)
from django.contrib.postgres.fields import ArrayField
from django.db import models
class Customer(models.Model):
# Here we define options user will ahve as payment method
CRYPTO = "CRYPTO"
CREDIT = "CREDIT"
OPTIONS = [
(CRYPTO, "cypto buyer"),
(CREDIT, "credit card buyer")
]
# Moment when user register
created_at = models.DateTimeField(auto_now=True)
# Some general informations
first_name = models.CharField(max_length=50, blank=True)
last_name = models.CharField(max_length=50, blank=True)
username = models.CharField(max_length=50, blank=True)
email = models.EmailField(max_length=250, blank=True)
# posibbile means of payment
type = models.CharField(
max_length = 20,
choices = OPTIONS,
default = 'CRYPTO'
)
# total number of NFTs bought
total_no_of_nfts = models.IntegerField(default=0)
# IDs of bought NFTs
nft_ids = ArrayField(models.IntegerField(null=True, blank=True), null=True, blank=True)
# ID of NFT metadata from NFTs ser bought (more on this in next part of this blog)
nft_metadata_ids = ArrayField(models.IntegerField(null=True, blank=True), null=True, blank=True)
# This is used just to return user name and last name when we print
def __str__(self):
return (f"{self.first_name} {self.last_name}")
Now when we have model
lets makemigration
and migrate
(this basically means to prepare our database for new customers entry). From project root directory
$py manage.py makemigrations
$py manage.py migrate
If we want to see our newly created model inside admin panel we need to add inside authentication/admin.py
from django.contrib import admin
from .models import Customer
admin.site.register(Customer)
Now if you go to admin and log as admin user (superuser we create on begining of this serias) you should be able to see new customer. Here is example:
With our new model in place let's turn to view.py
and update existig classes there. For model to work properly here is how our updated class can look like:
rom django.shortcuts import render, redirect
from django.views.generic import TemplateView
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from .forms import SignUpForm
from .models import Customer
class HomeView(TemplateView):
template_name="home.html"
def post(self, request):
# check to see if loggin in
user_name = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=user_name, password=password)
if user is not None:
login(request, user)
messages.success(request, "You have been logged in!")
return redirect("home")
else:
messages.success(request, "There was An Error login in, please try again")
return redirect("home")
def get(self, request):
# This is new part compared with previous version of this class
# Here we get Customer base don logged in user and pass to
# template to be render as part of his personal profile ones he is
# logged in
if str(request.user) == "AnonymousUser":
return render(request, "home.html", {})
name = str(request.user)
customer = Customer.objects.get(username=name)
return render(request, "home.html", {"customer": customer})
class LogoutUser(TemplateView):
def get(self, request):
logout(request)
messages.success(request, "You have been logged out!")
return redirect("home")
class RegisterUser(TemplateView):
# template_name="register.html"
def post(self, request):
# Everything what user send pass to our SignUpForm
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)
# We also added this part as I way to update Customer database
# in the moment when user register himself
Customer.objects.create(username=user, email=user.email, first_name=user.first_name, last_name=user.last_name)
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})
And last thing in this moment is to updated our home.html
template. New thing here is fact that beside check if user is authenticated we also need to check if he is crypto buyer or credit card buyer. Reason for this is fact that we need to show to different users different set of buttons (depending from their payment methods status). Here is new updated code in our home.html
{% extends "base.html" %}
{% block content%}
{% if user.is_authenticated %}
{% if customer.type == "CRYPTO"%}
<table class="table table-hover">
<thead class="table-dark">
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Total no. NFTs</th>
<th scope="col">Means of payment</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td> {{ customer.first_name }} {{ customer.last_name }} </td>
<td> {{ customer.email }} </td>
<td> {{ customer.total_no_of_nfts }} </td>
<td> {{ customer.type }} </td>
</tr>
</tbody>
</table>
<br>
<h1> Records crypto.. </h1>
{% else %}
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Total no. NFTs</th>
<th scope="col">Means of payment</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td> {{ customer.first_name }} {{ customer.last_name }} </td>
<td> {{ customer.email }} </td>
<td> {{ customer.total_no_of_nfts }} </td>
<td> {{ customer.type }} </td>
</tr>
</tbody>
</table>
<h1> Records credit card... <h1/>
{% endif %}
{% else %}
<h1> Login </h1>
<br/>
<form method="POST" action="{% url 'home' %}">
{% csrf_token %}
<div class="mb-3">
<input type="text" class="form-control" aria-describedby="emailHelp" placeholder="Username" name="username" required>
</div>
<div class="mb-3">
<input type="password" class="form-control" placeholder="Password" name="password" required>
</div>
<button type="submit" class="btn btn-secondary">Login</button>
</form>
{% endif %}
{% endblock content%}
We add in home.html
one more if/else
statment (to detemrin if he/she is cypto or credit card buyer) and we returned proper page accordingly. And then we just added some bootstrap tables which will be populated with customer context we pass to our template from our view.py
. And basiccally that is it. Now when user register himself and login he should see something like this for David Davidson crypto user:
Link to github code
Top comments (0)