DEV Community

ilija
ilija

Posted on

Web3 backend and smart contract development for Python developers Musical NFTs part 11: Django backend (user payment methods)

Now we need to allow user to select desired method of payment. And here we basically have only two options: crypto in form of some stabilcoin or credit card buyer. For this to happen we need to add few more things (here should be noticed that inside this simple example we can discover more generalizable Django pattern which can be used in many other situations when user need to post some data).

From basic element we will need: 1) One new form inside forms.py. Django use forms whenever you need to handle user input. We can of course do this in plain html and grab data in our views and then write to database. But instead we will use Django native mechanisam for this (Django forms); 2. Then we will need to update a little bit our HomeView class indside views.py to be able to handle another post method (when user update his/her payment method); and 3) inside our template home.html we need to have, beside user data we are passing currenlty as contex, also newly created form to handle change of payment method. This HTML file starts to be a bit complex but bascially what we do here is: 1) if user is authenticated check if he is CYPRO or CREDIT CARD buyer and deliver to him proper page. 2) if user is not authenticated show him login page.

Now let's start from forms.py inside our authentication folder. Inside this file we already have our SignUpForm class. Bellow that we need to add additional one: OrderForm.

 class OrderForm(ModelForm):
        class Meta:
            model = Customer
            fields = ("type",)
Enter fullscreen mode Exit fullscreen mode

As you can see it is very simple class. We are just saying this forms is related to our Customer model and only field we need for our purpose is type. And if you remember type filed from our model class Customer have choice with two option: Credit card or Crypto. This will allow user to define which payment method he want to use for ordering our musical NFTs. Ones he choose we will offer to him different set of functionalities: 1) Stripe integration for credit card user and 2) direct crypto payment for crypto native users.

And now new HomeView class (explanations in code comments) can look something like this

class HomeView(TemplateView):

        def post(self, request):
                # There is two possible post method coming from our home page
                # 1. When user submit login details 
                # 2. When user submit update of payment method 
                # 1. In case of login
                if "username" in request.POST:
                    # 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")  
                # 2. In case user chaning payment method (this is new part)
                else:
                    # get curren user
                    user = Customer.objects.get(username=request.user)                
                    # we need to pass to our form user instance because we
                    # need to change already exsiting entry from our DB. And 
                    # that is why we need instance of that concreat user
                    # Second argument we are passing for keyword data is 
                    # actual data user submit from front end in our case: 
                    # crypto or credit card option 
                    form = OrderForm(instance=user, data=request.POST)
                    # here we are checking validiti od submited form
                    if form.is_valid():
                        # if everything was ok we can save change in our 
                        # database.  
                        form.save()
                        # push message to front-end for user to see
                        messages.success(request, "You successfully update payment method")
                        # redirect user to home page with new situation 
                        # reflecting update
                        return redirect("home")
                    messages.success(request, "There is error in updating your payment status")
                    return redirect("home")

        def get(self, request):
            if str(request.user) == "AnonymousUser":
                return render(request, "home.html", {})
            name = str(request.user)
            customer = Customer.objects.get(username=name)
            form = OrderForm()
            # Now we are returnig customer data plus our OrderForm
            return render(request, "home.html", {"customer": customer, "form": form})

Enter fullscreen mode Exit fullscreen mode

With this in place we can move to our home.html and change a bit (later on we will clean this html because it start looks cumbersome). Key parts are explained inside code


{% 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>
        </tr>
      </thead>
      <tbody>
        <tr>
            <td> {{ customer.first_name }} {{ customer.last_name }} </td>
            <td> {{ customer.email }} </td>
            <td> {{ customer.total_no_of_nfts }} </td>
            # Here is 4 item of this table we have our OrderForm. And this is
            # where we plug our view.py part realted to payment method
            <td><form action="" method="post">
              {%csrf_token%}

              {{form.as_p}}

              <input type="submit" value="Save" class="btn btn-secondary">
          </form>
            </td> 



          </tr>
        </tbody>
      </table>


      <br>
      <h1> Records crypto.. </h1>
      {% else %}
      <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>
          </tr>
        </thead>
        <tbody>
          <tr>
              <td> {{ customer.first_name }} {{ customer.last_name }} </td>
              <td> {{ customer.email }} </td>
              <td> {{ customer.total_no_of_nfts }} </td>
              <td><form action="" method="post">
                {%csrf_token%}
                {{form.as_p}}
                <input type="submit" value="Save" class="btn btn-secondary">
            </form>
              </td>             
            </tr>
          </tbody>
        </table>
        <br>
    <h1> Records credit card... </h1>
    {% endif %}
    {% else %}
    <div class="col-md-6 offset-md-3"> 
    <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> 
      </div>
{% endif %}
{% endblock content%}
Enter fullscreen mode Exit fullscreen mode

And now if you login as some user you will see something like this.

Image description

If user change his payment method, his data in database will be updated and he will be redirected to user page with proper set of functionalities reflecting his new payment status.

Top comments (0)