django views – hyperlinks with thumbnails

Question:

I’m brand new to django front-end web development.

I have an index.html in my templates folder which has two thumbnails for sign up or login, and clicking on them directs you to signup.html and login.html. I have included the respective urls for those in urls.py. I’m stuck as to how I can edit my views.py so that I can record which option the user takes in order to perform the directing. I’ve used hyperlinks and thumbnails in my HTML code.

Currently my views.py looks like this:

 from django.shortcuts import render
 from .models import Customer

 # Create your views here.
 def index(request):
    return render(request, 'newuser/index.html', {})

 def login(request):
    return render(request, 'newuser/login.html', {})

def signup(request):
    return render(request, 'newuser/signup.html', {})`

And urls.py:

from django.conf.urls import url 
from . import views

urlpatterns = [
    url(r'^$', views.index, name = 'index'),
    url(r'^login$', views.login, name = 'login'),
    url(r'^signup$', views.signup, name = 'signup'),
]

And finally, this is my index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title> Zucumber </title>
    <link rel = "stylesheet" href = "//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <link rel = "stylesheet" href = "//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/bootstrap-theme.min.css">
    <link href="https://fonts.googleapis.com/css?family=PT+Sans" rel="stylesheet"> 
    <link rel = "stylesheet" href = "{% static 'css/newuser.css' %}">
</head>
<body>
    <div class = "page-header">
        <h1> Welcome to My Site </h1>
    </div>
    <style>
      .container {
           margin-left: 300px;
           margin-right: 300px;
      }
   </style>
   <div class = "container">
       <div class="row">
           <div class="col-xs-6 col-md-3">
                <a href="signup" class="thumbnail">
                <img src="/static/img/signup.jpg" alt = "Sign Up as New User">
                </a>
                <h3> Sign Up </h3>
           </div>
           <div class="col-xs-6 col-md-3">
               <a href="login" class="thumbnail">
               <img src="/static/img/login.jpg" alt = "Log In as Existing User">
               </a>
               <h3> Log In </h3>
           </div>
       </div>
    </div>
</body>
</html>

Answers:

I’m not sure if i follow what you are asking exactly, but if its just the directing the user in the urls then you should use the url template tag with something like this

<a href="{% url 'signup' %}" class="thumbnail">
    <img src="/static/img/signup.jpg" alt = "Sign Up as New User">
</a>

<a href="{% url 'login' %}" class="thumbnail">
    <img src="/static/img/login.jpg" alt = "Log In as Existing User">
</a>

because you named the urls in urls.py you can reference them by name in the url template tag and it will figure out the full url.

for example as you named this one login

url(r'^login$', views.login, name = 'login'),

using the following

<a href="{% url 'login' %}" class="thumbnail">click here</a>

will cause it to render with the url http://yoursite.com/login

if you are actually looking to record the clicks the user makes that is slightly more involved and you probably want to setup some model to persist the data and then catch the clicks in the views somehow

Answered By: davidejones

Please avoid hard-coding urls in Django. You can use the power of reverse url matching here. Since you already have name assigned to your urls, you can have container in your index.html like this:

<div class = "container">
   <div class="row">
       <div class="col-xs-6 col-md-3">
            <a href="{% url 'signup' %}" class="thumbnail">
            <img src="/static/img/signup.jpg" alt = "Sign Up as New User">
            </a>
            <h3> Sign Up </h3>
       </div>
       <div class="col-xs-6 col-md-3">
           <a href="{% url 'login' %}" class="thumbnail">
           <img src="/static/img/login.jpg" alt = "Log In as Existing User">
           </a>
           <h3> Log In </h3>
       </div>
   </div>
</div>

This would help in redirecting to corresponding urls using your urls.py.

Next, you need to create a forms to be displayed on signup and login page. Since you’ve imported Customer from models, I’m assuming that you want to create signup and login for them.

So you can put in your forms.py:

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

from .models import Customer

class LoginForm(AuthenticationForm):
    username = forms.CharField(label="Username", max_length=30,
                               widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'username'}))
    password = forms.CharField(label="Password", max_length=30,
                widget=forms.PasswordInput(attrs={'class': 'form-control', 'name': 'password'}))


class SignUpForm(UserCreationForm):
    class Meta:
        model = Customer

In SignUpForm you can also specify the fields you want from the user while registering by providing fields as a list of attributes of Customer model.

In your login.html you can provide a space for your LoginForm to render like:

<form action="{% url 'login' %}" method="POST">
  {% csrf_token %}
  {% for field in form %}
    <b>{{ field.label }}</b>:
    {{ field }}<br>
    {{ field.errors }}
  {% endfor %}
  <input type="submit" value="Sumbit">
</form>

Similarly your signup.html would also provide form like this:

<form action="{% url 'signup' %}" method="POST">
  {% csrf_token %}
  {% for field in form %}
    <b>{{ field.label }}</b>:
    {{ field }}<br>
    {{ field.errors }}<br>
  {% endfor %}
  <input type="submit" value="Sumbit">
</form>

Finally edit your login and signup views to store the data like this:

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.contrib.auth import authenticate, login, logout

from .forms import LoginForm, SignUpForm

def login(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)
        if user is not None:
            login(request, user)
            return HttpResponse("Logged in", status=200)
        else:
            form = LoginForm(request.POST)
            context = {'form': form}
            return render(request, 'login.html', context=context, status=401)
    if request.method == 'GET':
        form = LoginForm(None)
        context = {'form': form}
        return render(request, 'login.html', context=context)


def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            form.save()
        else:
            context = {'form': form}
            return render(request, 'signup.html', context=context)
        return HttpResponse("Registered Successfully", status=200)

    if request.method == 'GET':
        form = SignUpForm(None)
        context = {'form': form}
        return render(request, 'signup.html', context=context)

Note here that I’ve used login and logout functionality of django.contrib.auth. This may not be what you want for your application. But the idea is pretty much similar.

Answered By: Sanyam Khurana