Following Django Tutorial (CRM)-Part11

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. New app Agent

  • stop server
  • type “python manage.py startapp agents” on console
  • go to settings.py
  • add new app
  • create urls.py file under agents app(folder)
  • write/copy below code into urls.py for now
from django.urls import path


app_name = 'agents'

urlpatterns = [
	
]
  • go to urls.py under root project, djangocrm for me
  • add path for agents
path('agents/', include('agents.urls', namespace="agents")),

2. Agent list views

  • go to views.py under agents
  • write/copy below code
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
from leads.models import Agent


class AgentListView(LoginRequiredMixin, generic.ListView):
	template_name = "agent_list.html"

	def get_queryset(self):
		return Agent.objects.all()
  • go to urls.py under agents
  • import AgentListView and add path
  • create agent_list.html file
  • in my case, under root template folder since I would like to see all the templates in one folder.
  • if you created template folder under leads app separately, you can create another template folder under agents app to manage separately.
  • in the tutorial video, he is creating under agents separately
  • write/copy below code. it is basically same as lead_list.html content
{% extends "base.html" %}

{% block content %}

<section class="text-gray-600 body-font">
	<div class="container px-5 py-24 mx-auto flex flex-wrap">
		<div class="w-full mb-6 py-6 flex justify-between items-center border-b border-gray-200">
			<div>
				<h1 class="text-4xl text-gray-800">Agents</h1>
			</div>
			<div>
				<a href="{% url 'agents:agent-create' %}" class="text-gray-500 hover:text-blue-500">
					Create a new agent
				</a>
			</div>
		</div>
		<div class="flex flex-wrap -m-4">
			{% for agent in object_list %}
				<div class="p-4 lg:w-1/2 md:w-full">
					<div class="flex border-2 rounded-lg border-gray-200 border-opacity-50 p-8 sm:flex-row flex-col">
						<div class="w-16 h-16 sm:mr-8 sm:mb-0 mb-4 inline-flex items-center justify-center rounded-full bg-indigo-100 text-indigo-500 flex-shrink-0">
							<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-8 h-8" viewBox="0 0 24 24">
								<path d="M22 12h-4l-3 9L9 3l-3 9H2"></path>
							</svg>
						</div>
						<div class="flex-grow">
							<h2 class="text-gray-900 text-lg title-font font-medium mb-3">
								{{ agent.user.username }}
							</h2>
							<p class="leading-relaxed text-base">
								Blue bottle crucifix vinyl post-ironic four dollar toast vegan taxidermy. Gastropub indxgo juice poutine.
							</p>
							<a href="#" class="mt-3 text-indigo-500 inline-flex items-center">
								View lead details
								<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-4 h-4 ml-2" viewBox="0 0 24 24">
									<path d="M5 12h14M12 5l7 7-7 7"></path>
								</svg>
							</a>
						</div>
					</div>
				</div>
			{% endfor %}
		</div>
	</div>
</section>

{% endblock content %}
  • again, just copy all code and paste it. then, you will see code in better format
  • save files and go to localhost:8000/agents to check if it is there

3. Agent Create View

  • create forms.py file under agents app
  • write/copy below code
from django import forms
from leads.models import Agent


class AgentModelForm(forms.ModelForm):
	class Meta:
		model = Agent
		fields = (
			'user',
		)
  • go to views.py under agents app
  • import reverse and form
  • create AgentCreate class
  • here is the code for class
class AgentCreateView(LoginRequiredMixin, generic.CreateView):
	template_name = "agent_create.html"
	form_class = AgentModelForm

	def get_success_url(self):
		return reverse("agents:agent-list")

	def form_valid(self, form):
		agent = form.save(commit=False)
		agent.organisation = self.request.user.userprofile
		agent.save()
		return super(AgentCreateView, self).form_valid(form)
  • create agent_create.html file
  • write/copy below code, same format as lead_create.html
{% extends "base.html" %}

{% block content %}
	<a href="{% url 'agents:agent-list' %}">Go back to agents</a>
	<hr />
	<h1>Create a new agent</h1>
	<form method="post">
		{% csrf_token %}
		{{ form.as_p }}
		<button type="submit">Submit</button>
	</form>
{% endblock content %}
  • go to urls.py under agent app
  • import create view and add path (changed name for list view too)
  • while testing, got error related to organisation.
  • did delete db and migrate again and solved.

4. Agent Detail View

  • go to views.py under agent app
  • write/copy code below
class AgentDetailView(LoginRequiredMixin, generic.DetailView):
	template_name = "agent_detail.html"
	context_object_name = "agent"

	def get_queryset(self):
		return Agent.objects.all()
  • go to urls.py under agent app
  • import AgentDetailView and add path
  • create agent_detail.html file
  • copy lead_detail.html content and paste
  • replace some of the content there. Lead to Agent and some href
  • you can copy the code below instead
{% extends "base.html" %}

{% 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 text-indigo-500 border-b-2 border-indigo-500 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="#" class="flex-grow border-b-2 border-gray-300 py-2 text-lg px-1">
					Update Details
				</a>
			</div>
			<p class="leading-relaxed mb-4">
				Fam locavore kickstarter distillery. Mixtape chillwave tumeric sriracha taximy chia microdosing tilde DIY. XOXO fam inxigo juiceramps cornhole raw denim forage brooklyn. Everyday carry +1 seitan poutine tumeric. Gastropub blue bottle austin listicle pour-over, neutra jean.
			</p>
			<div class="flex border-t border-gray-200 py-2">
				<span class="text-gray-500">Age</span>
				<span class="ml-auto text-gray-900">{{ lead.age }}</span>
			</div>
			<div class="flex border-t border-gray-200 py-2">
				<span class="text-gray-500">Location</span>
				<span class="ml-auto text-gray-900">Dummy Location</span>
			</div>
			<div class="flex border-t border-b mb-6 border-gray-200 py-2">
				<span class="text-gray-500">Cell Phone</span>
				<span class="ml-auto text-gray-900">+654651651</span>
			</div>
			<div class="flex">
				<button class="flex ml-auto text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded">Button</button>
				<button class="rounded-full w-10 h-10 bg-gray-200 p-0 border-0 inline-flex items-center justify-center text-gray-500 ml-4">
				<svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-5 h-5" viewBox="0 0 24 24">
					<path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"></path>
				</svg>
				</button>
			</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 %}
  • add correct href link on agent_list.html
  • add agents on navbar.html

5. Agent Update View

  • create class for agent update on views.py
class AgentUpdateView(LoginRequiredMixin, generic.UpdateView):
	template_name = "agent_update.html"
	form_class = AgentModelForm

	def get_success_url(self):
		return reverse("agents:agent-list")

	def get_queryset(self):
		return Agent.objects.all()
  • import update view and add path on urls.py
  • create agent_update.html file and copy the content from lead_update.html
  • you can copy below code
{% extends "base.html" %}

{% 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.as_p }}
					<button type="submit">Submit</button>
				</form>
				<a href="#" class="w-1/2 mt-3 flex ml-auto text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded">
					Delete
				</a>
			</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 %}
  • add update href on agent_detail.html

6. Agent Delete View

  • create AgentDeleteView class on views.py
class AgentDeleteView(LoginRequiredMixin, generic.DeleteView):
	template_name = "agent_delete.html"
	context_object_name = "agent"

	def get_success_url(self):
		return reverse("agents:agent-list")

	def get_queryset(self):
		return Agent.objects.all()
  • import and add path of AgentDeleteView on urls.py
  • create agent_delete.html file and copy the code below
{% extends "base.html" %}

{% block content %}
	<a href="{% url 'agents:agent-list' %}">Go back to agents</a>
	<hr />
	<h1>Are you sure you want to delete this agent?</h1>
	<form method="post">
		{% csrf_token %}
		{{ form.as_p }}
		<button type="submit">Submit</button>
	</form>
{% endblock content %}
  • go to agent_update.html and add delete href link
  • save the files, go to browser to test all CRUD+L working properly.

done for this post