Following Django Tutorial (CRM)-Part13

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. reset password

  • go to urls.py under djangocrm
  • import some views related to password reset and add paths
  • PasswordResetView is the form view to submit the form takes/send to your email with link.
  • PasswordResetDoneView is just the template view email sent.
  • PasswordResetConfirmView is the form view resetting the password.
  • in video, it is going back and forth between files, so I just wrote them all when finished.
  • for the detail and descriptions, please watch their video to watch
  • under registration, create password reset related html files.
  • go to login.html
  • add “forgot password?” button
  • go to password_reset_form.html
  • write/copy code below, basically same as login
{% extends 'base.html' %}

{% block content %}

<form method="post">
	{% csrf_token %}
	{{ form.as_p }}
	<button type="submit">Reset Password</button>
	<hr />
	<a href="{% url 'login' %}">Already have an account?</a>
</form>

{% endblock content %}
  • go to password_reset_done.html
  • write/copy code below
{% extends 'base.html' %}

{% block content %}

	<h1>We have sent you an email to confirm your password reset.</h1>

{% endblock content %}
  • go to password_reset_email.html
  • write/copy code below
You've requested to reset your password

Please go to the following URL to enter your new password:

{{ protocol }}://{{ domain }}/password-reset-confirm/{{ uid }}/{{ token }}/
  • go to password_reset_confirm.html
  • write/copy code below, basically same as password_reset_form
{% extends 'base.html' %}

{% block content %}

<h1>Enter your new password</h1>

<form method="post">
	{% csrf_token %}
	{{ form.as_p }}
	<button type="submit">Confirm new password</button>
	<hr />
	<a href="{% url 'login' %}">Already have an account?</a>
</form>

{% endblock content %}
  • go to password_reset_complete.html
  • write/copy code below
{% extends 'base.html' %}

{% block content %}

	<h1>Password reset complete</h1>

	<p>You have successfully reset your password. Click <a href="{% url 'login' %}">here</a> to login</p>



{% endblock content %}

2. Split assigned and unassigned leads

  • go to views.py under leads app
  • currently LeadListView is showing all the leads
  • split that into two different, assigned and unassigned.
  • copy/write/edit code like below
class LeadListView(LoginRequiredMixin, generic.ListView):
	template_name = "lead_list.html"
	context_object_name = "leads"

	def get_queryset(self):
		user = self.request.user
		# initial queryset of leads for the entire organisation
		if user.is_organisor:
			queryset = Lead.objects.filter(
				organisation=user.userprofile,
				agent__isnull=False
			)
		else:
			queryset = Lead.objects.filter(
				organisation=user.agent.organisation,
				agent__isnull=False
			)
			# filter for the agent that is logged in
			queryset = queryset.filter(agent__user=user)
		return queryset

	def get_context_data(self, **kwargs):
		context = super(LeadListView, self).get_context_data(**kwargs)
		user = self.request.user
		if user.is_organisor:
			queryset = Lead.objects.filter(
				organisation=user.userprofile,
				agent__isnull=True
			)
			context.update({
				"unassigned_leads": queryset
			})
		return context
  • go to lead_list.html
  • copy/write code below after the div wrapped for loop.
  • check the screenshot below the code where to copy.
{% if unassigned_leads.exists %}
			<div class="mt-5 flex flex-wrap -m-4">
				<div class="p-4 w-full">
					<h1 class="text-4xl text-gray-800">Unassigned leads</h1>
				</div>
				{% for lead in unassigned_leads %}
					<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">
									{{ lead.first_name }} {{ lead.last_name }}
								</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="{% url 'leads:lead-detail' lead.pk %}" 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>
		{% endif %}
  • save the files and go to the browser
  • login to admin and check the leads page to see if it is split.

3. assigning agent

  • in video, it is going back and forth between files, so I just wrote them all when finished.
  • for the detail and descriptions, please watch their video to watch
  • go to views.py under leads app
  • import AssignAgentForm
  • create AssignAgentView class like below code at the bottom
class AssignAgentView(OrganisorAndLoginRequiredMixin, generic.FormView):
	template_name = "assign_agent.html"
	form_class = AssignAgentForm

	def get_form_kwargs(self, **kwargs):
		kwargs = super(AssignAgentView, self).get_form_kwargs(**kwargs)
		kwargs.update({
			"request": self.request
		})
		return kwargs

	def get_success_url(self):
		return reverse("leads:lead-list")

	def form_valid(self, form):
		agent = form.cleaned_data["agent"]
		lead = Lead.objects.get(id=self.kwargs["pk"])
		lead.agent = agent
		lead.save()
		return super(AssignAgentView, self).form_valid(form)
  • go to forms.py
  • import Agent
  • create AssignAgentForm class like below code at the bottom
class AssignAgentForm(forms.Form):
	agent = forms.ModelChoiceField(queryset=Agent.objects.none())

	def __init__(self, *args, **kwargs):
		request = kwargs.pop("request")
		agents = Agent.objects.filter(organisation=request.user.userprofile)
		super(AssignAgentForm, self).__init__(*args,**kwargs)
		self.fields["agent"].queryset = agents
  • go to urls.py
  • import AssignAgentView and ad paths
  • create new file name assign_agent.html
  • write/copy code below, basically same as create/update form.
{% extends "base.html" %}

{% block content %}
	<a href="{% url 'leads:lead-list' %}">Go back to leads</a>
	<hr />
	<h1>Assign an agent to this lead</h1>
	<form method="post">
		{% csrf_token %}
		{{ form.as_p }}
		<button type="submit">Submit</button>
	</form>
{% endblock content %}
  • go to lead_list.html
  • change “view lead details” button to “Assign an agent” and edit the url.
  • save the files edited, go to browser
  • check if you can assign agent.

done for this post