Following Django Tutorial (CRM)-Part14

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. Categorize Model

  • go to modles.py under leads app
  • create category variable under Lead class
  • add Category class
  • go to admin.py under leads app
  • import Category and add site.
  • stop the server makemigrations and migrate
  • run server and go to browser
  • go to admin page and create new categories

2. Category List View

  • go to models.py
  • add organisation on Category
  • should makemigrations and migrate, but python will give you some msgs to select.
  • this organisation should have been added when creating Category class.
  • here is the work around the video explains.
  • first give null and blank as true for organisation
  • then makemigrations and migrate
  • delete null and blank from organisation again
  • makemigrations again
  • you will get another msgs to choose.
  • hit 2, Ignore for now and migrate
  • you will get error because of null values.
  • run server and go to admin page, don’t worry of red messages for now.
  • go to Categorys and add organisations for all categories
  • stop the server
  • migrate again, it will be succeed
  • go to views.py
  • import Category model
  • create class for list view like below.
  • remember, below codes are complete code for this video,
  • in the video, he is writing code on different files back and forth with explanation.
class CategoryListView(LoginRequiredMixin, generic.ListView):
	template_name = "category_list.html"
	context_object_name = "category_list"

	def get_context_data(self, **kwargs):
		context = super(CategoryListView, self).get_context_data(**kwargs)
		user = self.request.user

		if user.is_organisor:
			queryset = Lead.objects.filter(
				organisation=user.userprofile
			)
		else:
			queryset = Lead.objects.filter(
				organisation=user.agent.organisation
			)
		return context

		context.update({
			"unassigned_lead_count": queryset.filter(category__isnull=True).count()
		})


	def get_queryset(self):
		user = self.request.user
		if user.is_organisor:
			queryset = Category.objects.filter(
				organisation=user.userprofile
			)
		else:
			queryset = Category.objects.filter(
				organisation=user.agent.organisation
			)
		return queryset
  • create category_list.html
  • go to https://tailblocks.cc/
  • looking for the table view
  • in video and my case, used second of pricing
  • copy the code and paste in between the block content
  • edit some of them, or you can copy below
{% extends "base.html" %}

{% block content %}

<section class="text-gray-600 body-font">
  <div class="container px-5 py-24 mx-auto">
    <div class="flex flex-col text-center w-full mb-20">
      <h1 class="sm:text-4xl text-3xl font-medium title-font mb-2 text-gray-900">Category</h1>
      <p class="lg:w-2/3 mx-auto leading-relaxed text-base">
		  These categories segment the leads
	  </p>
    </div>
    <div class="lg:w-2/3 w-full mx-auto overflow-auto">
      <table class="table-auto w-full text-left whitespace-no-wrap">
        <thead>
          <tr>
            <th class="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100 rounded-tl rounded-bl">Name</th>
            <th class="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100">Lead Count</th>
          </tr>
        </thead>
        <tbody>
			<tr>
				<td class="px-4 py-3">Unassigned</td>
				<td class="px-4 py-3">{{ unassigned_lead_count }}</td>
			</tr>
			{% for category in category_list %}
				<tr>
					<td class="px-4 py-3">{{ category.name }}</td>
					<td class="px-4 py-3">todo count</td>
				</tr>
		  	{% endfor %}
        </tbody>
      </table>
    </div>
  </div>
</section>
GitHub

{% endblock content %}
  • go to urls.py
  • import category list view
  • add path
  • the reason I created categoires above lead-detail view is getting error if I add path at the bottom.
  • that’s because python is reading path from the top to bottom.
  • when it reaches to <pk>, it is expecting numbers.
  • this is in case use <pk>, if use <int:pk> will be different. you can watch the video for this case.
  • go to browser and check on leads/category

3. category detail view

  • go to models.py
  • add related_name on Leads.
  • for more description of what it is, please watch their video.
  • makemigrations and migrate
  • go to views.py
  • write/copy the below code
class CategoryDetailView(LoginRequiredMixin, generic.DetailView):
	template_name = "category_detail.html"
	context_object_name = "category"


	def get_queryset(self):
		user = self.request.user
		if user.is_organisor:
			queryset = Category.objects.filter(
				organisation=user.userprofile
				)
		else:
			queryset = Category.objects.filter(
				organisation=user.agent.organisation
				)
		return queryset
  • create category_detail.html file
  • copy below code
{% extends "base.html" %}

{% block content %}

<section class="text-gray-600 body-font">
  <div class="container px-5 py-24 mx-auto">
    <div class="flex flex-col text-center w-full mb-20">
      <h1 class="sm:text-4xl text-3xl font-medium title-font mb-2 text-gray-900">{{ category.name }}</h1>
      <p class="lg:w-2/3 mx-auto leading-relaxed text-base">
		  These are the leads under this category
	  </p>
    </div>
    <div class="lg:w-2/3 w-full mx-auto overflow-auto">
      <table class="table-auto w-full text-left whitespace-no-wrap">
        <thead>
          <tr>
            <th class="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100 rounded-tl rounded-bl">First Name</th>
            <th class="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100">Last Name</th>
          </tr>
        </thead>
        <tbody>
			{% for lead in category.leads.all %}
				<tr>
					<td class="px-4 py-3">{{ lead.first_name }}</td>
					<td class="px-4 py-3">{{ lead.last_name }}</td>
				</tr>
		  	{% endfor %}
        </tbody>
      </table>
    </div>
  </div>
</section>

{% endblock content %}
  • go to urls.py
  • import category detail view and add path
  • go to category_list.html
  • add link to category detail
  • go to lead_list.html
  • add link to category list

4. category update view

  • go to category_detail.html
  • add link to lead-detail
  • go to forms.py
  • create LeadCategoryUpdateForm as below
class LeadCategoryUpdateForm(forms.ModelForm):
	class Meta:
		model = Lead
		fields = (
			'category',
		)
  • go to views.py
  • import the form created above
  • create related class like below code
class LeadCategoryUpdateView(LoginRequiredMixin, generic.UpdateView):
	template_name = "lead_category_update.html"
	form_class = LeadCategoryUpdateForm


	def get_queryset(self):
		user = self.request.user
		if user.is_organisor:
			queryset = Lead.objects.filter(
				organisation=user.userprofile
				)
		else:
			queryset = Lead.objects.filter(
				organisation=user.agent.organisation
				)
			queryset = queryset.filter(agent__user=user)
		return queryset

	def get_success_url(self):
		return reverse("leads:lead-detail", kwargs={"pk": self.get_object().id})
  • go to urls.py
  • import and add path related view
  • create lead_category_update.html file
  • you can copy from lead_update.html and edit or 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">
					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.as_p }}
					<button type="submit">Submit</button>
				</form>
				<a href="{% url 'leads:lead-delete' lead.pk %}" 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 %}
  • go to lead_update.html and add link and change Reviews to Category
  • go to lead_detail.html
  • add link and change Reviews to Category