Following Django Tutorial (CRM)-Part15

This post is for myself to remember how to build Django project.
I did follow the tutorial from the JustDjango Learn website free tutorial.
And this is the fourth tutorial named Getting Started With Django.
I am not going over all the details and descriptions for each part. There are good explanations on video of the JustDjango Learn. So, visit their site and try their tutorials if you need more details. Also, the orders of this post and their video might be different because I put things first what I think should come first.

I am doing this on Windows 10 with just Windows PowerShell. Not using virtual machines at all.

1. Install and basic settings for new package

pip install django-crispy-forms
  • then, add on requirements.txt by typing below command
  • or you can just add directly from the editor like below screenshot
pip freeze > requirements.txt
  • go to seetings.py
  • add crispy-forms on installed apps
pip install crispy-tailwind
  • add on requirements again
  • add apps on settings.py
  • and set as default template pack

2. use of crispy form

  • go to login.html
  • you can copy the below code or edit yourself
{% extends 'base.html' %}
{% load tailwind_filters %}

{% block content %}

<div class="max-w-lg mx-auto">

	<div class="py-5 border-b border-gray-200 mt-5">
		<a class="hover:text-blue-500" href="{% url 'signup' %}">
			Don't have an account?
		</a>
	</div>
	<form method="post" class="mt-5">
		{% csrf_token %}
		{{ form|crispy }}
		<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
			Login
		</button>
	</form>
	<div class="py-5 border-t border-gray-200 mt-5">
		<a class="hover:text-blue-500" href="{% url 'reset-password' %}">
			Forgot password?
		</a>
	</div>
</div>

{% endblock content %}

3. edit all the forms in the project

  • I will just put the completed code for each templates of forms.
  • password_reset_confrim.html
{% extends 'base.html' %}
{% load tailwind_filters %}

{% block content %}

<div class="max-w-lg mx-auto">
	<h1 class="text-4xl text-gray-800">Enter your new password</h1>

	<form method="post" class="mt-5">
		{% csrf_token %}
		{{ form|crispy }}
		<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
			Confirm new password
		</button>
	</form>
	<div class="py-5 border-t border-gray-200 mt-5">
		<a class="hover:text-blue-500" href="{% url 'signup' %}">
			Already have an account?
		</a>
	</div>
</div>


{% endblock content %}
  • password_reset_form.html
{% extends 'base.html' %}
{% load tailwind_filters %}

{% block content %}

<div class="max-w-lg mx-auto">
	<h1 class="text-4xl text-gray-800">Reset your password</h1>

	<form method="post" class="mt-5">
		{% csrf_token %}
		{{ form|crispy }}
		<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
			Reset Password
		</button>
	</form>
	<div class="py-5 border-t border-gray-200 mt-5">
		<a class="hover:text-blue-500" href="{% url 'login' %}">
			Already have an account?
		</a>
	</div>	
</div>


{% endblock content %}
  • signup.html
{% extends 'base.html' %}
{% load tailwind_filters %}

{% block content %}

<div class="max-w-lg mx-auto">
	<form method="post" class="mt-5">
		{% csrf_token %}
		{{ form|crispy }}
		<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
			Signup
		</button>
	</form>
	<div class="py-5 border-t border-gray-200 mt-5">
		<a class="hover:text-blue-500" href="{% url 'login' %}">
			Already have an account?
		</a>
	</div>
</div>

{% endblock content %}
  • lead_create.html
{% extends "base.html" %}
{% load tailwind_filters %}

{% block content %}

<div class="max-w-lg mx-auto">
	<a class="hover:text-blue-500" href="{% url 'leads:lead-list' %}">
		Go back to leads
	</a>
	<div class="py-5 border-t border-gray-200">
		<h1 class="text-4xl text-gray-800">Create a new lead</h1>
	</div>
	<form method="post" class="mt-5">
		{% csrf_token %}
		{{ form|crispy }}
		<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
			Submit
		</button>
	</form>
</div>
	
{% endblock content %}
  • lead_update.html
{% extends "base.html" %}
{% load tailwind_filters %}

{% block content %}

<section class="text-gray-600 body-font overflow-hidden">
	<div class="container px-5 py-24 mx-auto">
		<div class="lg:w-4/5 mx-auto flex flex-wrap">
			<div class="lg:w-1/2 w-full lg:pr-10 lg:py-6 mb-6 lg:mb-0">
				<h2 class="text-sm title-font text-gray-500 tracking-widest">
					LEAD
				</h2>
				<h1 class="text-gray-900 text-3xl title-font font-medium mb-4">
					{{ lead.first_name }} {{ lead.last_name }}
				</h1>
				<div class="flex mb-4">
					<a href="{% url 'leads:lead-detail' lead.pk %}" class="flex-grow border-b-2 border-gray-300 py-2 text-lg px-1">
						Description
					</a>
					<a href="{% url 'leads:lead-category-update' lead.pk %}" class="flex-grow border-b-2 border-gray-300 py-2 text-lg px-1">
						Category
					</a>
					<a href="{% url 'leads:lead-update' lead.pk %}" class="flex-grow text-indigo-500 border-b-2 border-indigo-500 py-2 text-lg px-1">
						Update Details
					</a>
				</div>
				<form method="post">
					{% csrf_token %}
					{{ form|crispy }}
					<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
						Submit
					</button>
				</form>
				<div class="mt-5 py-5 border-t border-gray-200">
					<a href="{% url 'leads:lead-delete' lead.pk %}" class="w-1/2 mt-3 text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded">
						Delete
					</a>
				</div>
			</div>
			<img alt="ecommerce" class="lg:w-1/2 w-full lg:h-auto h-64 object-cover object-center rounded" src="https://dummyimage.com/400x400">
		</div>
	</div>
</section>
{% endblock content %}
  • lead_category_update.html
{% extends "base.html" %}
{% load tailwind_filters %}

{% block content %}

<section class="text-gray-600 body-font overflow-hidden">
	<div class="container px-5 py-24 mx-auto">
		<div class="lg:w-4/5 mx-auto flex flex-wrap">
			<div class="lg:w-1/2 w-full lg:pr-10 lg:py-6 mb-6 lg:mb-0">
				<h2 class="text-sm title-font text-gray-500 tracking-widest">
					LEAD
				</h2>
				<h1 class="text-gray-900 text-3xl title-font font-medium mb-4">
					{{ lead.first_name }} {{ lead.last_name }}
				</h1>
				<div class="flex mb-4">
					<a href="{% url 'leads:lead-detail' lead.pk %}" class="flex-grow border-b-2 border-gray-300 py-2 text-lg px-1">
						Description
					</a>
					<a href="{% url 'leads:lead-category-update' lead.pk %}" class="flex-grow text-indigo-500 border-b-2 border-indigo-500 py-2 text-lg px-1">
						Category
					</a>
					<a href="{% url 'leads:lead-update' lead.pk %}" class="flex-grow border-b-2 border-gray-300 py-2 text-lg px-1">
						Update Details
					</a>
				</div>
				<form method="post">
					{% csrf_token %}
					{{ form|crispy }}
					<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
						Submit
					</button>
				</form>
			</div>
			<img alt="ecommerce" class="lg:w-1/2 w-full lg:h-auto h-64 object-cover object-center rounded" src="https://dummyimage.com/400x400">
		</div>
	</div>
</section>
{% endblock content %}
  • lead_delete.html
{% extends "base.html" %}
{% load tailwind_filters %}

{% block content %}

<div class="max-w-lg mx-auto">
	<a class="hover:text-blue-500" href="{% url 'leads:lead-list' %}">
		Go back to leads
	</a>
	<div class="py-5 border-t border-gray-200">
		<h1 class="text-3xl text-gray-800">
			Are you sure you want to delete this lead?
		</h1>
	</div>
	<form method="post" class="mt-5">
		{% csrf_token %}
		{{ form|crispy }}
		<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
			Submit
		</button>
	</form>
</div>
	
{% endblock content %}
  • agent_create.html
{% extends "base.html" %}

{% load tailwind_filters %}

{% block content %}

<div class="max-w-lg mx-auto">
	<a class="hover:text-blue-500" href="{% url 'agents:agent-list' %}">
		Go back to agents
	</a>
	<div class="py-5 border-t border-gray-200">
		<h1 class="text-4xl text-gray-800">Create a new agent</h1>
	</div>
	<form method="post" class="mt-5">
		{% csrf_token %}
		{{ form|crispy }}
		<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
			Submit
		</button>
	</form>
</div>
	
{% endblock content %}
  • agent_update.html
{% extends "base.html" %}
{% load tailwind_filters %}

{% block content %}

<section class="text-gray-600 body-font overflow-hidden">
	<div class="container px-5 py-24 mx-auto">
		<div class="lg:w-4/5 mx-auto flex flex-wrap">
			<div class="lg:w-1/2 w-full lg:pr-10 lg:py-6 mb-6 lg:mb-0">
				<h2 class="text-sm title-font text-gray-500 tracking-widest">
					AGENT
				</h2>
				<h1 class="text-gray-900 text-3xl title-font font-medium mb-4">
					{{ agent.user.username }}
				</h1>
				<div class="flex mb-4">
					<a href="{% url 'agents:agent-detail' agent.pk %}" class="flex-grow border-b-2 border-gray-300 py-2 text-lg px-1">
						Overview
					</a>
					<a class="flex-grow border-b-2 border-gray-300 py-2 text-lg px-1">
						Reviews
					</a>
					<a href="{% url 'agents:agent-update' agent.pk %}" class="flex-grow text-indigo-500 border-b-2 border-indigo-500 py-2 text-lg px-1">
						Update Details
					</a>
				</div>
				<form method="post">
					{% csrf_token %}
					{{ form|crispy }}
					<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
						Submit
					</button>
				</form>
				<div class="mt-5 py-5 border-t border-gray-200">
					<a href="{% url 'agents:agent-delete' agent.pk %}" class="w-1/2 mt-3 text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded">
						Delete
					</a>
				</div>
			</div>
			<img alt="ecommerce" class="lg:w-1/2 w-full lg:h-auto h-64 object-cover object-center rounded" src="https://dummyimage.com/400x400">
		</div>
	</div>
</section>
{% endblock content %}
  • agent_delete.html
{% extends "base.html" %}
{% load tailwind_filters %}

{% block content %}

<div class="max-w-lg mx-auto">
	<a class="hover:text-blue-500" href="{% url 'agents:agent-list' %}">
		Go back to agents
	</a>
	<div class="py-5 border-t border-gray-200">
		<h1 class="text-3xl text-gray-800">
			Are you sure you want to delete this agent?
		</h1>
	</div>
	<form method="post" class="mt-5">
		{% csrf_token %}
		{{ form|crispy }}
		<button type="submit" class="w-full text-white bg-blue-500 hover:bg-blue-600 px-3 py-2 rounded-md">
			Submit
		</button>
	</form>
</div>
{% endblock content %}
  • check all the forms in the project and apply to any missing ones.

4. add more fields on Lead

  • go to models.py under leads app
  • add some more fields under Lead
description = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
phone_number = models.CharField(max_length=20)
email = models.EmailField()
  • stop the server and run makemigrations
  • you will get messages
  • for date_added, select “1” to provide default value and type “timezone.now”
  • for rest of them select “1” to provide default value and type ”(two single quotation meaning blank).
  • run migrate and run server
  • go to forms.py under leads app
  • add three more fields of four just created under LeadModelForm.
  • date_added is not editable, so except that.
  • go to views.py
  • add below code under LeadCreateView class under form_valid function
lead = form.save(commit=False)
lead.organisation = self.request.user.userprofile
lead.save()

5. assign correct values into set as static values

  • go to lead_list.html
  • below the names display, there is random description as static.
  • there are two.
  • change them to
{{ lead.description }}
  • go to lead_detail.html
  • change location to email and cell phone to phone number
  • and assign correct value there

6. log out redirect

  • currently, if you logout, it will redirect to django logout page
  • to give it redirect to landing page,
  • go to settings.py
  • add below code under the LOGIN_URL at the bottom
LOGOUT_REDIRECT_URL = "/"
  • now go to browser and check the whole site if it is working fine for all or not

done for this post