Code
(1) Create a motherboard
Copy org-list.html to the templates directory, create a new base.html, and cut the content of org-list.html into it
Then modify the address of the static file (css, is, image and media)
(2) Organization homepage routing
from organization.views import OrgView path('org_list/',OrgView.as_view(),name ='org_list'),
(3) Institutional views
class OrgView(View): '''Course institution''' def get(self,request): return render(request,'org-list.html')
(4) org-list.html inherits base
{#templates/org-list.html#} {% extends'base.html' %} {% block title %} List of Course Institutions {% endblock %}
Visit: http://127.0.0.1:8000/org_list/You can see the org_list page
(5) Modify the base template
Cut the contents of the two blocks of custom_bread and content in base into org-list.html
base.html
org-list.html
(1) Enter the xadmin background to add a city
The organization here is static and fixed, and the region is dynamic, obtained from the database
(2) Modify the models of the institution and add an institution category field
organization/models.py:
class CourseOrg(models.Model): ORG_CHOICES = ( ("pxjg", u"training organization"), ("gx", u"high school"), ("gr", u"personal"), ) #Add field category = models.CharField(max_length=20, choices=ORG_CHOICES, verbose_name=u"organization category", default="pxjg")
class CourseOrg(models.Model): ORG_CHOICES = ( ("pxjg", u"training organization"), ("gx", u"high school"), ("gr", u"personal"), ) name = models.CharField('Organization Name',max_length=50) desc = models.TextField('Organization Description') category = models.CharField(max_length=20, choices=ORG_CHOICES, verbose_name=u"organization category", default="pxjg") click_nums = models.IntegerField('Number of clicks',default=0) fav_nums = models.IntegerField('Number of collections',default=0) image = models.ImageField('logo',upload_to='org/%Y%m',max_length=100) address = models.CharField('Organization address',max_length=150,) city = models.ForeignKey(CityDict,verbose_name='City',on_delete=models.CASCADE) add_time = models.DateTimeField(default=datetime.now) class Meta: verbose_name ='Course institution' verbose_name_plural = verbose_name def __str__(self): return self.name
After adding makemigrations-->>migrate
(3) Add organization
Upload the picture of the organization when adding organization information
Create a new directory "media" under the project directory to store uploaded pictures
In the setting, we need to configure which root directory we store the file under
#settings.py # Set the path of the uploaded file MEDIA_URL ='/media/' MEDIA_ROOT = os.path.join(BASE_DIR,'media') #Specify the root directory
Will splice the complete path with upload
"/Media/org/2018/month/picture name"
Then add ten institutions in the background
(1) Write the view function organization/views.py
class OrgView(View): '''Course institution''' def get(self,request): # Take out all course institutions all_orgs = CourseOrg.objects.all() org_onums = all_orgs.count() # Take out all cities all_citys = CityDict.objects.all() return render(request, "org-list.html", { "all_orgs": all_orgs, "all_citys": all_citys, 'org_onums':org_onums, })
(2) Modify org-list.html
Show the total number of institutions
Show city
Display organization
Then you have to do the following settings
How to convert image field into image address
The image in the database is saved in string format. It is a relative path. It cannot be retrieved directly. The path must be completed.
data-url="{{ MEDIA_URL }}{{ course_org.image }}"
MEDIA_URL ='/media/', this is set in the previous settings
To use {{ MEDIA_URL }}, first add a media processor in TEMPLATES in settings:'django.core.context_processors.media'
Then add the URL that handles the corresponding path of the image
TEMPLATES = [ { 'BACKEND':'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR,'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', #Add image processor, in order to add MEDIA_URL in front of the course list 'django.template.context_processors.media', ], }, }, ]
urls.py
from django.views.static import serve from MxOnline.settings import MEDIA_ROOT # Process the url displayed by the picture, use Django's own serve, and pass in the parameters to tell it which path to find, we have the configured path MEDIAROOT re_path(r'^media/(?P<path>.*)', serve, {"document_root": MEDIA_ROOT })
4.places
Use the pagination artifact django-pure-pagination for pagination, the usage method is introduced on github
(1) Installation
pip install django-pure-pagination
(2) Add in settings
INSTALLED_APPS = ( ... 'pure_pagination', )
(3) How to use in views
class OrgView(View): '''Course institution''' def get(self, request): # All course institutions all_orgs = CourseOrg.objects.all() # How many institutions org_nums = all_orgs.count() # All cities all_citys = CityDict.objects.all() # Pagination of course institutions # Try to get the page parameters passed by the front desk get request # If it is an illegal configuration parameter, return to the first page by default try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 # Here refers to five from allorg, each page shows five p = Paginator(all_orgs, 5, request=request) orgs = p.page(page) return render(request, "org-list.html", { "all_orgs": orgs, "all_citys": all_citys, "org_nums": org_nums, })
(4) Modify org-list.html
This becomes "all_orgs.object_list"
Paging function
<div class="pageturn"> <ul class="pagelist"> {% if all_orgs.has_previous %} <li class="long"><a href="?{{ all_orgs.previous_page_number.querystring }}">Previous page</a></li> {% endif %} {% for page in all_orgs.pages %} {% if page %} {% ifequal page all_orgs.number %} <li class="active"><a href="?{{ page.querystring }}">{{ page }}</a></li> {% else %} <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li> {% endifequal %} {% else %} <li class="none"><a href="">...</a></li> {% endif %} {% endfor %} {% if all_orgs.has_next %} <li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}">Next page</a></li> {% endif %} </ul> </div>
Changed to display 2 lists per page, as follows:
(1) City list filtering
Background processing city filtering
class OrgView(View): '''Course institution''' def get(self, request): # All course institutions all_orgs = CourseOrg.objects.all() # How many institutions org_nums = all_orgs.count() # All cities all_citys = CityDict.objects.all() city_id = request.GET.get('city','') if city_id: all_orgs = all_orgs.filter(city_id=int(city_id)) # Pagination of course institutions # Try to get the page parameters passed by the front desk get request # If it is an illegal configuration parameter, return to the first page by default try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 # Here refers to five from allorg, each page shows five p = Paginator(all_orgs, 2, request=request) orgs = p.page(page) return render(request, "org-list.html", { "all_orgs": orgs, "all_citys": all_citys, "org_nums": org_nums, 'city_id':city_id, })
Front page
<h2>Location</h2> <div class="more">More</div> <div class="cont"> <a href="?ct="><span class="{% ifequal city_id'' %}active2{% endifequal %}">All</span></a> {% for city in all_citys %} <a href="?city={{ city.id }}"><span class="{% ifequal city.id|stringformat:'i' city_id %}active2{% endifequal %}">{{ city.name }}</span></a> {% endfor %} </div>
Because city.id is an int type, it needs to be converted into a string and then compared.
{% ifequal city_id'' %} If it is empty, it means that no city is selected, and "all" is "active"
(2) Category screening
Background processing
# Category filter category = request.GET.get('ct','') if category: all_orgs = all_orgs.filter(category=category) # How many institutions org_nums = all_orgs.count()
Put org_numsf at the back, first filter in the statistical quantity
In the template
<h2>Organization category</h2> <div class="cont"> <a href="?city={{ city_id }}"><span class="{% ifequal category'' %}active2{% endifequal %}">All</span></a> <a href="?ct=pxjg&city={{ city_id }}"><span class="{% ifequal category'pxjg' %}active2{% endifequal %}">Training institutions</span></a> <a href="?ct=gx&city={{ city_id }}"><span class="{% ifequal category'gx' %}active2{% endifequal %}">College</span></a> <a href="?ct=gr&city={{ city_id }}"><span class="{% ifequal category'gr' %}active2{% endifequal %}">Personal</span></a> </div>
<h2>Location</h2> <div class="more">More</div> <div class="cont"> <a href="?ct={{ category }}"><span class="{% ifequal city_id'' %}active2{% endifequal %}">All</span></a> {% for city in all_citys %} <a href="?city={{ city.id }}&ct={{ category }}"><span class="{% ifequal city_id city.id|stringformat:"i" %}active2{% endifequal %}">{{ city.name }}</span></a> {% endfor %} </div>
Link cities and classifications:
(3) Ranking screening of course institutions
Background processing
Ranked by clicks, only the first three are taken
# Popular course institution ranking hot_orgs = all_orgs.order_by('-click_nums')[:3]
In the template
<div class="right companyrank layout"> <div class="head">Teaching institution ranking</div> {% for curent_org in hot_orgs %} <dl class="des"> <dt class="num fl">{{ foorloop.counter }}</dt> <dd> <a href="/company/2/"><h1>{{ curent_org.name }}</h1></a> <p>{{ curent_org.address }}</p> </dd> </dl> {% endfor %} </div>
When looping, the built-in variable forloop.counter takes the current loop to the number of times
(4) Selection of the number of learners and courses
Add two fields for the number of learners and the number of courses in models
students = models.IntegerField("Number of students",default=0) course_nums = models.IntegerField("Number of courses",default=0)
class CourseOrg(models.Model): ORG_CHOICES = ( ("pxjg", u"training organization"), ("gx", u"high school"), ("gr", u"personal"), ) name = models.CharField('Organization Name',max_length=50) desc = models.TextField('Organization Description') category = models.CharField(max_length=20, choices=ORG_CHOICES, verbose_name=u"organization category", default="pxjg") click_nums = models.IntegerField('Number of clicks',default=0) fav_nums = models.IntegerField('Number of collections',default=0) students = models.IntegerField("Number of students",default=0) course_nums = models.IntegerField("Number of courses",default=0) image = models.ImageField('logo',upload_to='org/%Y/%m',max_length=100) address = models.CharField('Organization address',max_length=150,) city = models.ForeignKey(CityDict,verbose_name='City',on_delete=models.CASCADE) add_time = models.DateTimeField(default=datetime.now) class Meta: verbose_name ='Course institution' verbose_name_plural = verbose_name def __str__(self): return self.name
migrate to the database
Background processing
# Screening of number of learners and number of courses sort = request.GET.get('sort', "") if sort: if sort == "students": all_orgs = all_orgs.order_by("-students") elif sort == "courses": all_orgs = all_orgs.order_by("-course_nums")
class OrgView(View): '''Course institution''' def get(self, request): # All course institutions all_orgs = CourseOrg.objects.all() # All cities all_citys = CityDict.objects.all() # City filter city_id = request.GET.get('city','') if city_id: all_orgs = all_orgs.filter(city_id=int(city_id)) # Category filter category = request.GET.get('ct','') if category: all_orgs = all_orgs.filter(category=category) # Popular course institution ranking hot_orgs = all_orgs.order_by('-click_nums')[:3] # Screening of number of learners and number of courses sort = request.GET.get('sort', "") if sort: if sort == "students": all_orgs = all_orgs.order_by("-students") elif sort == "courses": all_orgs = all_orgs.order_by("-course_nums") # How many institutions org_nums = all_orgs.count() # Pagination of course institutions # Try to get the page parameters passed by the front desk get request # If it is an illegal configuration parameter, return to the first page by default try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 # Here refers to five from allorg, each page shows five p = Paginator(all_orgs, 2, request=request) orgs = p.page(page) return render(request, "org-list.html", { "all_orgs": orgs, "all_citys": all_citys, "org_nums": org_nums, 'city_id':city_id, "category": category, 'hot_orgs':hot_orgs, 'sort':sort, })
front end
<div class="head"> <ul class="tab_header"> <li class="{% if sort =='' %}active{% endif %}"><a href="?sort=students&ct={{ category }}&city={{ city_id }}">All</a a></li> <li class="{% if sort =='students' %}active{% endif %}"><a href="?sort=students&ct={{ category }}&city={{ city_id }}">Number of students ↓</a></li> <li class="{% if sort =='courses' %}active{% endif %}"><a href="?sort=courses&ct={{ category }}&city={{ city_id }}">Number of courses ↓</a></li> </ul> </div>
(1) Realize with ModelForm
Create the forms.py file in the organazition directory
# organization/forms.py from django import forms from operation.models import UserAsk class UserAskForm(forms.Form): '''I want to consult''' class Meta: model = UserAsk fields = ['name','mobile','course_name']
(2) include routing distribution
# MxOnline/urls.py import xadmin from django.urls import path,include,re_path from django.views.generic import TemplateView from users.views import LoginView,RegisterView,ActiveUserView,ForgetPwdView,ResetView,ModifyPwdView from organization.views import OrgView from django.views.static import serve from MxOnline.settings import MEDIA_ROOT urlpatterns = [ path('xadmin/', xadmin.site.urls), path('', TemplateView.as_view(template_name='index.html'),name='index'), path('login/',LoginView.as_view(),name ='login'), path('register/',RegisterView.as_view(),name ='register'), path('captcha/',include('captcha.urls')), re_path('active/(?P<active_code>.*)/',ActiveUserView.as_view(),name='user_active'), path('forget/',ForgetPwdView.as_view(),name='forget_pwd'), re_path('reset/(?P<active_code>.*)/', ResetView.as_view(), name='reset_pwd'), path('modify_pwd/', ModifyPwdView.as_view(), name='modify_pwd'), path('org_list/',OrgView.as_view(),name ='org_list'), # Process the url displayed by the picture, use Django's own serve, pass in the parameters to tell it which path to find, we have the configured path MEDIAROOT re_path(r'^media/(?P<path>.*)', serve, {"document_root": MEDIA_ROOT }), ]
Delete the route of org_list and change it to include
path("org/", include('organization.urls', namespace="org")),
Use namespaces to prevent duplication
Then add in organization/urls.py
# organization/urls.py from organization.views import OrgView from django.urls import path,re_path # To write the name of the app app_name = "organization" urlpatterns = [ path('list/',OrgView.as_view(),name='org_list'), ]
Ways of using namespaces in html:
Modify the "link to the course institution" in base.html
<li class="active" ><a href="{% url'org:org_list' %}">Teaching institution</a></li>
(3) View function
from django.http import HttpResponse from .forms import UserAskForm class AddUserAskView(View): """ User add consultation """ def post(self, request): userask_form = UserAskForm(request.POST) if userask_form.is_valid(): user_ask = userask_form.save(commit=True) # If the save is successful, return the json string, and the content type is to tell the browser to return the data type return HttpResponse('{"status":"success"}', content_type='application/json') else: # If the save fails, return the json string, and pass the error message of the form to the front end through msg return HttpResponse('{"status":"fail", "msg":"Adding error"}', content_type='application/json')
# organization/views.py from django.shortcuts import render from django.views.generic import View from .models import CourseOrg,CityDict from pure_pagination import Paginator, EmptyPage, PageNotAnInteger from django.http import HttpResponse from .forms import UserAskForm class OrgView(View): '''Course institution''' def get(self, request): # All course institutions all_orgs = CourseOrg.objects.all() # All cities all_citys = CityDict.objects.all() # City filter city_id = request.GET.get('city','') if city_id: all_orgs = all_orgs.filter(city_id=int(city_id)) # Category filter category = request.GET.get('ct','') if category: all_orgs = all_orgs.filter(category=category) # Popular course institution ranking hot_orgs = all_orgs.order_by('-click_nums')[:3] # Screening of number of learners and number of courses sort = request.GET.get('sort', "") if sort: if sort == "students": all_orgs = all_orgs.order_by("-students") elif sort == "courses": all_orgs = all_orgs.order_by("-course_nums") # How many institutions org_nums = all_orgs.count() # Pagination of course institutions # Try to get the page parameters passed by the front desk get request # If it is an illegal configuration parameter, return to the first page by default try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 # Here refers to five from allorg, each page shows five p = Paginator(all_orgs, 2, request=request) orgs = p.page(page) return render(request, "org-list.html", { "all_orgs": orgs, "all_citys": all_citys, "org_nums": org_nums, 'city_id':city_id, "category": category, 'hot_orgs':hot_orgs, 'sort':sort, }) class AddUserAskView(View): """ User add consultation """ def post(self, request): userask_form = UserAskForm(request.POST) if userask_form.is_valid(): user_ask = userask_form.save(commit=True) # If the save is successful, return the json string, and the content type is to tell the browser to return the data type return HttpResponse('{"status":"success"}', content_type='application/json') else: # If the save fails, return the json string, and pass the error message of the form to the front end through msg return HttpResponse('{"status":"fail", "msg":"Adding error"}', content_type='application/json')
Ajax submission is used here, the page will not be refreshed as a whole, and a Json data should be returned to the front end
HttpResponse can specify the type of data passed to the front end
(4) Configure url
# organization/urls.py from organization.views import OrgView,AddUserAskView from django.urls import path,re_path # To write the name of the app app_name = "organization" urlpatterns = [ path('list/',OrgView.as_view(),name='org_list'), path('add_ask/', AddUserAskView.as_view(), name="add_ask"), ]
(5) Customize a mobile phone number verification method in ModelForm
# organization/forms.py import re from django import forms from operation.models import UserAsk class UserAskForm(forms.ModelForm): class Meta: model = UserAsk fields = ['name','mobile','course_name'] def clean_mobile(self): """ Verify that the phone number is legal """ mobile = self.cleaned_data['mobile'] REGEX_MOBILE = "^1[358]\d{9}$|^147\d{8}$|176\d{8}$" p = re.compile(REGEX_MOBILE) if p.match(mobile): return mobile else: raise forms.ValidationError(u"Mobile phone number is illegal", code="mobile_invalid")
(6) Submit using Ajax in the template
org-list.html
<div class="right companyright"> <div class="head">I want to learn</div> <form class="rightform" id="jsStayForm"> <div> <img src="{% static'images/rightform1.png' %}"/> <input type="text" name="name" id="companyName" placeholder="First name" maxlength="25"/> </div> <div> <img src="{% static'images/rightform2.png' %}"/> <input type="text" name="mobile" id="companyMobile" placeholder="Contact number"/> </div> <div> <img src="{% static'images/rightform3.png' %}"/> <input type="text" name="course_name" id="companyAddress" placeholder="course name" maxlength="50"/> </div> <p class="error company-tips" id="jsCompanyTips"></p> <input class="btn" type="text" id="jsStayBtn" value="Consult now>"/> {% csrf_token %} </form> </div>
<script> $(function () { $('#jsStayBtn').on('click', function () { $.ajax({ cache: false, type: "POST", url: "{% url "org:add_ask" %}", data: $('#jsStayForm').serialize(), async: true, success: function (data) { if (data.status =='success') { $('#jsStayForm')[0].reset(); alrt("Submitted successfully") } else if (data.status =='fail') { $('#jsCompanyTips').html(data.msg) } }, }); }); }) </script>
{#templates/org-list.html#} {% extends'base.html' %} {% load staticfiles %} {% block title %}List of course institutions{% endblock %} {% block custom_bread %} <section> <div class="wp"> <ul class="crumbs"> <li><a href="index.html">Home</a>></li> <li>Course institution</li> </ul> </div> </section> {% endblock %} {% block content %} <section> <div class="wp butler_list_box list"> <div class='left'> <div class="listoptions"> <ul> <li> <h2>Organization category</h2> <div class="cont"> <a href="?city={{ city_id }}"><span class="{% ifequal category'' %}active2{% endifequal %}">All</span></a> <a href="?ct=pxjg&city={{ city_id }}"><span class="{% ifequal category'pxjg' %}active2{% endifequal %}">Training institutions</span></a> <a href="?ct=gx&city={{ city_id }}"><span class="{% ifequal category'gx' %}active2{% endifequal %}">College</span></a> <a href="?ct=gr&city={{ city_id }}"><span class="{% ifequal category'gr' %}active2{% endifequal %}">Personal</span></a> </div> </li> <li> <h2>Location</h2> <div class="more">More</div> <div class="cont"> <a href="?ct={{ category }}"><span class="{% ifequal city_id'' %}active2{% endifequal %}">All</span></a> {% for city in all_citys %} <a href="?city={{ city.id }}&ct={{ category }}"><span class="{% ifequal city_id city.id|stringformat:"i" %}active2{% endifequal %}">{{ city.name }}</span></a> {% endfor %} </div> </li> </ul> </div> <div class="all">Total <span class="key">{{ org_nums }}</span>home</div> <div class="butler_list company list"> <div class="layout"> <div class="head"> <ul class="tab_header"> <li class="{% if sort =='' %}active{% endif %}"><a href="?sort=students&ct={{ category }}&city={{ city_id }}">All</a></li> <li class="{% if sort =='students' %}active{% endif %}"><a href="?sort=students&ct={{ category }}&city={{ city_id }}">Number of students↓</a></li> <li class="{% if sort =='courses' %}active{% endif %}"><a href="?sort=courses&ct={{ category }}&city={{ city_id }}">Number of courses↓</a></li> </ul> </div> {% for course_org in all_orgs.object_list %} <dl class="des difdes"> <dt> <a href="org-detail-homepage.html"> <img width="200" height="120" class="scrollLoading" data-url="{{ MEDIA_URL }}{{ course_org.image }}"/> </a> </dt> <dd> <div class="clearfix"> <a href="org-detail-homepage.html"> <h1>{{ course_org.name }}</h1> <div class="pic fl"> <img src="{% static'images/authentication.png' %}"/> <img src="{% static'images/gold.png' %}"/> </div> </a> </div> <ul class="cont"> <li class="first"><p class="pic9">Number of courses: <span>1</span></p> <p class="c7">Number of learners: <span>1000</span></p></li> <li class="c8" style="padding-left:18px;">Zhongguancun North Street, Haidian District, Beijing</li> <li class="pic10" style="padding-left:18px;">Classic course: <a href="/diary/19/">c language basics introduction</a> <a href="/diary/16/">Database Basics</a> </li> </ul> </dd> <div class="buy start_groupbuy jsShowPerfect2" data-id="22"><br/>Contact<br/>Services</div> </dl> {% endfor %} </div> <div class="pageturn"> <ul class="pagelist"> {% if all_orgs.has_previous %} <li class="long"><a href="?{{ all_orgs.previous_page_number.querystring }}">Previous page</a></li> {% endif %} {% for page in all_orgs.pages %} {% if page %} {% ifequal page all_orgs.number %} <li class="active"><a href="?{{ page.querystring }}">{{ page }}</a></li> {% else %} <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li> {% endifequal %} {% else %} <li class="none"><a href="">...</a></li> {% endif %} {% endfor %} {% if all_orgs.has_next %} <li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}">Next page</a></li> {% endif %} </ul> </div> </div> </div> <div class="right companyright"> <div class="head">I want to learn</div> <form class="rightform" id="jsStayForm"> <div> <img src="{% static'images/rightform1.png' %}"/> <input type="text" name="name" id="companyName" placeholder="First name" maxlength="25"/> </div> <div> <img src="{% static'images/rightform2.png' %}"/> <input type="text" name="mobile" id="companyMobile" placeholder="Contact number"/> </div> <div> <img src="{% static'images/rightform3.png' %}"/> <input type="text" name="course_name" id="companyAddress" placeholder="course name" maxlength="50"/> </div> <p class="error company-tips" id="jsCompanyTips"></p> <input class="btn" type="text" id="jsStayBtn" value="Consult now>"/> {% csrf_token %} </form> </div> <div class="right companyrank layout"> <div class="head">Teaching institution ranking</div> {% for curent_org in hot_orgs %} <dl class="des"> <dt class="num fl">{{ foorloop.counter }}</dt> <dd> <a href="/company/2/"><h1>{{ curent_org.name }}</h1></a> <p>{{ curent_org.address }}</p> </dd> </dl> {% endfor %} </div> </div> </section> {% endblock %} <script> $(function () { $('#jsStayBtn').on('click', function () { $.ajax({ cache: false, type: "POST", url: "{% url "org:add_ask" %}", data: $('#jsStayForm').serialize(), async: true, success: function (data) { if (data.status =='success') { $('#jsStayForm')[0].reset(); alrt("Submitted successfully") } else if (data.status =='fail') { $('#jsCompanyTips').html(data.msg) } }, }); }); }) </script>
When the submitted data is illegal
When it is legal, a success message will be displayed and the data will be saved to the database
(1) Add a foreign key to courses
from organization.models import CourseOrg course_org = models.ForeignKey(CourseOrg, on_delete=models.CASCADE, verbose_name="ownership", null=True, blank=True)
# course/models.py from datetime import datetime from django.db import models from organization.models import CourseOrg class Course(models.Model): DEGREE_CHOICES = ( ("cj", "Beginner"), ("zj", "Intermediate"), ("gj", "Advanced") ) name = models.CharField("Course Name",max_length=50) desc = models.CharField("Course Description", max_length=300) detail = models.TextField("Course Details") degree = models.CharField('Difficulty',choices=DEGREE_CHOICES, max_length=2) learn_times = models.IntegerField("Learning time (minutes)",default=0) students = models.IntegerField("Number of students",default=0) fav_nums = models.IntegerField("Number of Favorites",default=0) image = models.ImageField("Cover image",upload_to="courses/%Y/%m",max_length=100) click_nums = models.IntegerField("Number of clicks",default=0) add_time = models.DateTimeField("Add Time",default=datetime.now,) course_org = models.ForeignKey(CourseOrg, on_delete=models.CASCADE, verbose_name="ownership", null=True, blank=True) class Meta: verbose_name = "Course" verbose_name_plural = verbose_name def __str__(self): return self.name
Add courses and lecturers in the background
(2) Template
Copy the four files of the course organization page to the templates directory
Create a new template, name it "org_base.html", copy the content of org-detail-homepage.html into it
Add block, modify static file path
{#templates/org_base.html#} {% load staticfiles %} <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> <title>{% block title %}Organization homepage{% endblock %}</title> <link rel="stylesheet" type="text/css" href="{% static'css/reset.css' %}"> <link rel="stylesheet" type="text/css" href="{% static'css/animate.css' %}"> <link rel="stylesheet" type="text/css" href="{% static'css/style.css' %}"> <link rel="stylesheet" type="text/css" href="{% static'js/plugins/queryCity/css/cityLayout.css' %}"> {% block custom_css %}{% endblock %} <script src="{% static'js/jquery.min.js' %}" type="text/javascript"></script> <script src="{% static'js/jquery-migrate-1.2.1.min.js' %}" type="text/javascript"></script> {% block custom_js %}{% endblock %} </head> <body> <section class="headerwrap headerwrap2"> <header> <div class="header2 header"> <div class="top"> <div class="wp"> <div class="fl"> <p>Contact information: <b>3333333333</b></p> </div> <a style="color:white" class="fr registerbtn" href="register.html">Register</a> <a style="color:white" class="fr loginbtn" href="login.html">Login</a> </div> </div> <div class="middle companyheader"> <div class="wp"> <img class="fl" style="width: 112px;height: 103px" src="{% static'media/org/2016/11/imooc.png' %}"/> <div class="head fl"> <h1> MOOC <img src="{% static'images/authentication.png' %}"/> <img src="{% static'images/gold.png' %}"/> </h1> <p class="fl"> <span class="fl" style="margin-top:8px;color:#848484;">Recommendation index: </span> <span class="precision company-credit" data-star-scope="5.0"></span> <span class="key">5.0</span> </p> </div> <div class="btn fr collectionbtn notlogin "data-favid="22" data-fav-type="1"> Favorites </div> </div> </div> </div> </header> </section> <section> <div class="wp"> <ul class="crumbs"> <li><a href="index.html">Home</a>></li> <li><a href="org-list.html">Course institutions</a>></li> <li>{% block page_path %}Organization homepage{% endblock %}</li> </ul> </div> </section> <section> <div class="wp list personal_list comp"> <div class="left"> <ul> <li class="active2"><a href="org-detail-homepage.html">Organization Homepage</a></li> <li class=""><a href="org-detail-course.html">Institutional Courses</a></li> <li class=""><a href="org-detail-desc.html">Organization introduction</a></li> <li class=""><a href="org-detail-teachers.html">Organization Lecturer</a></li> </ul> </div> {% block right_form %} {% endblock %} <div class="head"> <h1>Organization introduction</h1> <a class="green fr more" href="org-detail-desc.html">View more> </a> </div> <div class="cont"> <p> </p><h1 class="ue_t" label="Title center" name="tc" style="border-bottom-color: #cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;text-align:center;margin:0px 0px 20px;"><span style="color:#c0504d; ">[Type document title]</span></h1><p style="text-align:center;"><strong class="ue_t">[Type document subtitle]</strong></p>< h3><span class="ue_t" style="font-family:幼圆">[Title1]</span></h3><p class="ue_t" style="text-indent:2em;"> For the library on the "Insert" tab, the items in it and the overall appearance of the document are coordinated in design. You can use these libraries to insert tables, headers, footers, lists, covers, and other document building blocks. The pictures, diagrams, or diagrams you create will also be consistent with the appearance of the current document. </p><p class="ue_t" style="text-indent:2em;"><img src="../media/courses/ueditor/57aa86a0000145c512000460_20161210234050_865.jpg" title="" alt="57aa86a0000145c512000460.jpg"/> </p><h3>< span class="ue_t" style="font-family:幼圆">[title 2]</span></h3><p><img src="http://api.map.baidu.com/staticimage ?center=116.410899,39.863624&zoom=11&width=530&height=340&markers=116.404,39.915" width="530" height="340"/> </p><p class="ue_t" style="text-indent:2em; ">On the "Home" tab, you can easily change the format of the selected text in the document by choosing a look for the selected text from the quick style library. You can also use other controls on the Start tab to directly format text. Most controls allow you to choose whether to use the current theme appearance or a directly specified format. </p><h3><span class="ue_t" style="font-family:幼圆">[Title 3]</span></h3><p> 2016-12-10</p><p class="ue_t">For the library on the "Insert" tab, the design has fully considered the coordination between the items and the overall appearance of the document. You can use these libraries to insert tables, headers, footers, lists, covers, and other document building blocks. The pictures, diagrams, or diagrams you create will also be consistent with the appearance of the current document. </p><p class="ue_t"><br/> </p><p><br/></p><p><br/></p><a href="/company/desc/22/"><span class="green">[see more]</span></a></div> </div> </section> <!--sidebar start--> <section> <ul class="sidebar"> <li class="qq"> <a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=2023525077&site=qq&menu=yes"></a> </li> <li class="totop"></li> </ul> </section> <!--sidebar end--> <!--header start--> </div> <!--Pop up provinces and cities--> <script src="{% static'js/selectUi.js' %}" type='text/javascript'></script> <script type="text/javascript" src="{% static'js/plugins/laydate/laydate.js' %}"></script> <script src="{% static'js/plugins/layer/layer.js' %}"></script> <script src="{% static'js/plugins/queryCity/js/public.js' %}" type="text/javascript"></script> <script type="text/javascript" src="{% static'js/plugins/jquery.raty.js' %}"></script> <script type="text/javascript"> //Favorite sharing //Favorite sharing function add_fav(current_elem, fav_id, fav_type){ $.ajax({ cache: false, type: "POST", url:"/org/add_fav/", data:{'fav_id':fav_id,'fav_type':fav_type}, async: true, beforeSend:function(xhr, settings){ xhr.setRequestHeader("X-CSRFToken", "5I2SlleZJOMUX9QbwYLUIAOshdrdpRcy"); }, success: function(data) { if(data.status =='fail'){ if(data.msg =='User is not logged in'){ win.loc.href="login.html"; }else{ alrt(data.msg) } }else if(data.status =='success'){ current_elem.text(data.msg) } }, }); } $('.collectionbtn').on('click', function(){ add_fav($(this), 1, 2); }); $(function(){ var $precision = $('.precision'), score = $precision.attr('data-star-scope'), option = { half: true, path:'../images/', precision: true, size: 24, starOff:'g_star.png', starOn:'r_star.png', starHalf:'h_star.png', hints: ['very bad','bad','average','good comment','very satisfied'], noRatedMsg: "I have not yet received reviews yet! ', readOnly: true, score: score }; $precision.raty(option); $('.jsFavBtn').on('click', function(){ var type = $(this).attr('data-fav-type'); if(type == '1'){ favPraise($(this),'fav' ,1,'collection'); }else if(type == '3'){ favPraise($(this),'fav' ,3 ); }else if(type == '11'){ favPraise($(this),'pra', 1); }else if(type == '4'){ favPraise($(this),'fav' ,4 ); } }); }) </script> <script type="text/javascript"> $(function() { $('.recordbtn1').click(function(){ $('.recordbox1').show(); }); $('.recordbtn2').click(function(){ $('.recordbox2').show(); }); $('.imgslide').unslider({ speed: 500,//The speed to animate each slide (in milliseconds) delay: 3000,//The delay between slide animations (in milliseconds) complete: function() {},//A function that gets called after every slide animation keys: true,//Enable keyboard (left, right) arrow shortcuts dots: true,//Display dot navigation fluid: false//Support responsive design. May break non-responsive designs }); var unslider = $('.imgslide').unslider(); $('.unslider-arrow').click(function() { var fn = this.className.split('')[1]; unslider.data('unslider')[fn](); }); }); </script> </body> </html>
(3) org-detail-home.html inherited template
Cut the three "rights" in org_base into home
(4) The url of the home page
from .views import OrgHomeView re_path('home/(?P<org_id>\d+)/', OrgHomeView.as_view(), name="org_home"),
(5) Back-end logic processing
class OrgHomeView(View): '''Organization Homepage''' def get(self,request,org_id): # Find course institution according to id course_org = CourseOrg.objects.get(id=int(org_id)) # Reverse query to all courses and teachers of the course institution all_courses = course_org.course_set.all()[:4] all_teacher = course_org.teacher_set.all()[:2] return render(request,'org-detail-homepage.html',{ 'course_org':course_org, 'all_courses':all_courses, 'all_teacher':all_teacher, })
(6) Show all courses
<div class="brief group_list"> {% for course in all_courses %} <div class="module1_5 box"> <a href="course-detail.html"><img width="214" src="{{ MEDIA_URL }}{{ course.image }}"/></a> <div class="des"> <a href="course-detail.html"><h2>{{ course.name }}</h2></a> <span class="fl">Class hours: <i class="key">{{ course.learn_times }}</i></span> <span class="fr">Number of participants: {{ course.students }}</span> </div> <div class="bottom"> <span class="fl">{{ course.course_org.name }}</span> <span class="star fr notlogin "data-favid="13" data-fav-type="4"> {{ course.fav_nums }} </span> </div> </div> {% endfor %} </div>
Modify the link in org-list.html and click on the organization to jump to the homepage of the corresponding organization
(6) Modify org-base.html
(7) Add a graphic field for the teacher
image = models.ImageField( default='', upload_to="teacher/%Y/%m", verbose_name="avatar", max_length=100)
(8) Display institution teachers
(9) Display organization details
Organization Homepage:
(1) Template file
Take out the different places (right) in org-detail-course.html
(2) Add url
re_path('course/(?P<org_id>\d+)/', OrgCourseView.as_view(), name="org_course"),
(3) views.py
class OrgCourseView(View): """ Institutional Course List Page """ def get(self, request, org_id): # Get the course institution according to id course_org = CourseOrg.objects.get(id = int(org_id)) # Find courses by course organization. Built-in variable, find the foreign key reference pointing to this field all_courses = course_org.course_set.all() return render(request,'org-detail-course.html',{ 'all_courses':all_courses, 'course_org': course_org, })
(4) Modify the link left in org-base.html
(5) Display institution courses, modify org-detail-course.html
<div class="brief group_list"> {% for course in all_courses %} <div class="module1_5 box"> <a class="comp-img-box" href="course-detail.html"> <img width="214" height="195" src="{{ MEDIA_URL }}{{ course.image }}"/> </a> <div class="des"> <a href="course-detail.html"><h2>{{ course.name }}</h2></a> <span class="fl">Class hours: <i class="key">{{ course.learn_times }}</i></span> <span class="fr">Number of students{{ course.students }}</span> </div> <div class="bottom"> <span class="fl">{{ course.course_org.name }}</span> <span class="star fr notlogin "data-favid="13" data-fav-type="4"> {{ course.fav_nums }} </span> </div> </div> {% endfor %}
Click "Institutional Courses" to see which courses are available
(6) Modification of the "active" status on the left
Because there is no value to determine which page is currently. So pass a current page parameter in the background
Modify org_base.html
<div class="left"> <ul> <li class="{% ifequal current_page'home' %}active2{% endifequal %}"><a href="{% url'org:org_home' course_org.id %}">Organization homepage</a></a></a> li> <li class="{% ifequal current_page'course' %}active2{% endifequal %}"><a href="{% url'org:org_course' course_org.id %}">Institutional courses</a></a></a> li> <li class="{% ifequal current_page'desc' %}active2{% endifequal %}"><a href="org-detail-desc.html">Organization introduction</a></li> <li class="{% ifequal current_page'teacher' %}active2{% endifequal %}"><a href="org-detail-teachers.html">Organization Lecturer</a></li> </ul> </div>
Modify the views and pass a current_page parameter to the front end to know which is currently activated
class OrgHomeView(View): '''Organization Homepage''' def get(self,request,org_id): current_page ='home' # Find course institution according to id course_org = CourseOrg.objects.get(id=int(org_id)) # Reverse query to all courses and teachers of the course institution all_courses = course_org.course_set.all()[:4] all_teacher = course_org.teacher_set.all()[:2] return render(request,'org-detail-homepage.html',{ 'course_org':course_org, 'all_courses':all_courses, 'all_teacher':all_teacher, 'current_page':current_page, })
class OrgCourseView(View): """ Institutional Course List Page """ def get(self, request, org_id): current_page ='course' # Get the course institution according to id course_org = CourseOrg.objects.get(id = int(org_id)) # Find courses by course organization. Built-in variable, find the foreign key reference pointing to this field all_courses = course_org.course_set.all() return render(request,'org-detail-course.html',{ 'all_courses':all_courses, 'course_org': course_org, 'current_page':current_page, })
(1) url
re_path('desc/(?P<org_id>\d+)/', OrgDescView.as_view(), name="org_desc"),
(2) views
class OrgDescView(View): '''Organization Introduction Page''' def get(self, request, org_id): current_page ='desc' # Get the course institution according to id course_org = CourseOrg.objects.get(id = int(org_id)) return render(request,'org-detail-desc.html',{ 'course_org': course_org, 'current_page':current_page, })
(1) url
re_path('teacher/(?P<org_id>\d+)/', OrgTeacherView.as_view(), name="org_teacher"),
(2) views
class OrgTeacherView(View): """ Institutional Teacher Page """ def get(self, request, org_id): current_page ='teacher' course_org = CourseOrg.objects.get(id = int(org_id)) all_teacher = course_org.teacher_set.all() return render(request,'org-detail-teachers.html',{ 'all_teacher':all_teacher, 'course_org': course_org, 'current_page':current_page, })
(3) org-detail-teachers.html
{% extends'org_base.html' %} {% load staticfiles %} <title>{% block title %}Organization Teacher Page--New Oriental {% endblock %}</title> {% block right_form %} <div class="right companycenter layout"> <div class="head"> <h1>Institutional Lecturer</h1> </div> <div class="messagelist"> <div class=" butler_list butler-fav-box"> {% for teacher in all_teacher %} <dl class="des users"> <dt> <a href=""> <img width="100" height="100" class="scrollLoading" data-url="{{ MEDIA_URL }}{{ teacher.image }}" src="{{ MEDIA_URL }}{{ teacher.image }} "/> </a> </dt> <dd> <h1> <a href=""> {{ teacher.name }}<span class="key">Certified</span> </a> </h1> <ul class="cont clearfix"> <li class="time">Work years: <span>{{ teacher.work_years }}</span></li> <li class="c7">Number of courses: <span>3</span></li> </ul> </dd> </dl> {% endfor %} </div> </div> </div> {% endblock %}
(4) Left in org-bae.html
<ul> <li class="{% ifequal current_page'home' %}active2{% endifequal %}"><a href="{% url'org:org_home' course_org.id %}">Organization homepage</a></a></a> li> <li class="{% ifequal current_page'course' %}active2{% endifequal %}"><a href="{% url'org:org_course' course_org.id %}">Institutional courses</a></a></a> li> <li class="{% ifequal current_page'desc' %}active2{% endifequal %}"><a href="{% url'org:org_desc' course_org.id %}">Introduction to institution</a></a></a> li> <li class="{% ifequal current_page'teacher' %}active2{% endifequal %}"><a href="{% url'org:org_teacher' course_org.id %}">Institutional lecturer</a></a></a> li> </ul>
(5) Modify the breadcrumbs, and click Institutional Courses should display Institutional Courses
base.html
Then reload page_path in the other four pages respectively
The other three methods are the same
(1) url
path('add_fav/', AddFavView.as_view(), name="add_fav"),
# organization/urls.py from organization.views import OrgView,AddUserAskView from django.urls import path,re_path from .views import OrgHomeView,OrgCourseView,OrgDescView,OrgTeacherView,AddFavView # To write the name of the app app_name = "organization" urlpatterns = [ path('list/',OrgView.as_view(),name='org_list'), path('add_ask/', AddUserAskView.as_view(), name="add_ask"), re_path('home/(?P<org_id>\d+)/', OrgHomeView.as_view(), name="org_home"), re_path('course/(?P<org_id>\d+)/', OrgCourseView.as_view(), name="org_course"), re_path('desc/(?P<org_id>\d+)/', OrgDescView.as_view(), name="org_desc"), re_path('teacher/(?P<org_id>\d+)/', OrgTeacherView.as_view(), name="org_teacher"), path('add_fav/', AddFavView.as_view(), name="add_fav"), ]
# MxOnline/urls.py import xadmin from django.urls import path,include,re_path from django.views.generic import TemplateView from users.views import LoginView,RegisterView,ActiveUserView,ForgetPwdView,ResetView,ModifyPwdView from organization.views import OrgView from django.views.static import serve from MxOnline.settings import MEDIA_ROOT urlpatterns = [ path('xadmin/', xadmin.site.urls), path('', TemplateView.as_view(template_name='index.html'),name='index'), path('login/',LoginView.as_view(),name ='login'), path('register/',RegisterView.as_view(),name ='register'), path('captcha/',include('captcha.urls')), re_path('active/(?P<active_code>.*)/',ActiveUserView.as_view(),name='user_active'), path('forget/',ForgetPwdView.as_view(),name='forget_pwd'), re_path('reset/(?P<active_code>.*)/', ResetView.as_view(), name='reset_pwd'), path('modify_pwd/', ModifyPwdView.as_view(), name='modify_pwd'), path("org/", include('organization.urls', namespace="org")), # Process the url displayed by the picture, use Django's own serve, pass in the parameters to tell it which path to find, we have the configured path MEDIAROOT re_path(r'^media/(?P<path>.*)', serve, {"document_root": MEDIA_ROOT }), ]
(2) Background processing
class AddFavView(View): """ User favorites and unfavorites """ def post(self, request): fav_id = request.POST.get('fav_id', 0) # Prevent errors in the back int(fav_id) fav_type = request.POST.get('fav_type', 0) # Prevent int(fav_type) error if not request.user.is_authenticated: # When you are not logged in, return json to prompt you are not logged in. Jumping to the login page is done in ajax return HttpResponse('{"status":"fail", "msg":"User not logged in"}', content_type='application/json') exist_record = UserFavorite.objects.filter(user=request.user, fav_id=int(fav_id), fav_type=int(fav_type)) if exist_record: # If the record already exists, it means that the user unfavored exist_record.delete() return HttpResponse('{"status":"fail", "msg":"Uncollected"}', content_type='application/json') else: user_fav = UserFavorite() if int(fav_id)> 0 and int(fav_type)> 0: user_fav.user = request.user user_fav.fav_id = int(fav_id) user_fav.fav_type = int(fav_type) user_fav.save() return HttpResponse('{"status":"success", "msg":"Collection"}', content_type='application/json') else: return HttpResponse('{"status":"fail", "msg":"Collection error"}', content_type='application/json')
(3) Front-end Ajax
Ajax is placed in org_base.html
<script type="text/javascript"> //Favorite sharing //Favorite sharing function add_fav(current_elem, fav_id, fav_type){ $.ajax({ cache: false, type: "POST", url:"{% url'org:add_fav' %}", data:{'fav_id':fav_id,'fav_type':fav_type}, async: true, beforeSend:function(xhr, settings){ xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}"); }, success: function(data) { if(data.status =='fail'){ if(data.msg =='User is not logged in'){ win.loc.href="/login/"; }else{ alrt(data.msg) } }else if(data.status =='success'){ current_elem.text(data.msg) } }, }); } $('.collectionbtn').on('click', function(){ add_fav($(this), {{ course_org.id }}, 2); });
Visit the page and click "Favorites" in the upper right corner, you can find that it works normally
You can see the user's favorites in the database
Click "Favorite" again, it will prompt "Unfavorite"
(4) But there is another problem. After refreshing the page, "Favorite" becomes "Favorite" because when returning to the page, the status of the collection is not judged.
All you need to add a judgment in the views
# Determine the status of the collection has_fav = False if request.user.is_authenticated: if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2): has_fav = True
Add this judgment on all four pages
# organization/views.py from django.shortcuts import render from django.views.generic import View from .models import CourseOrg,CityDict from pure_pagination import Paginator, EmptyPage, PageNotAnInteger from django.http import HttpResponse from .forms import UserAskForm from operation.models import UserFavorite from django.contrib.auth import authenticate class OrgView(View): '''Course institution''' def get(self, request): # All course institutions all_orgs = CourseOrg.objects.all() # All cities all_citys = CityDict.objects.all() # City filter city_id = request.GET.get('city','') if city_id: all_orgs = all_orgs.filter(city_id=int(city_id)) # Category filter category = request.GET.get('ct','') if category: all_orgs = all_orgs.filter(category=category) # Popular course institution ranking hot_orgs = all_orgs.order_by('-click_nums')[:3] # Screening of number of learners and number of courses sort = request.GET.get('sort', "") if sort: if sort == "students": all_orgs = all_orgs.order_by("-students") elif sort == "courses": all_orgs = all_orgs.order_by("-course_nums") # How many institutions org_nums = all_orgs.count() # Pagination of course institutions # Try to get the page parameters passed by the front desk get request # If it is an illegal configuration parameter, return to the first page by default try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 # Here refers to five from allorg, each page shows five p = Paginator(all_orgs, 2, request=request) orgs = p.page(page) return render(request, "org-list.html", { "all_orgs": orgs, "all_citys": all_citys, "org_nums": org_nums, 'city_id':city_id, "category": category, 'hot_orgs':hot_orgs, 'sort':sort, }) class AddUserAskView(View): """ User add consultation """ def post(self, request): userask_form = UserAskForm(request.POST) if userask_form.is_valid(): user_ask = userask_form.save(commit=True) # If the save is successful, return the json string, and the content type is to tell the browser to return the data type return HttpResponse('{"status":"success"}', content_type='application/json') else: # If the save fails, return the json string, and pass the error message of the form to the front end through msg return HttpResponse('{"status":"fail", "msg":"Adding error"}', content_type='application/json') class OrgHomeView(View): '''Organization Homepage''' def get(self,request,org_id): current_page ='home' # Find course institution according to id course_org = CourseOrg.objects.get(id=int(org_id)) # Judging the collection status has_fav = False if request.user.is_authenticated: if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2): has_fav = True # Reverse query to all courses and teachers of the course institution all_courses = course_org.course_set.all()[:4] all_teacher = course_org.teacher_set.all()[:2] return render(request,'org-detail-homepage.html',{ 'course_org':course_org, 'all_courses':all_courses, 'all_teacher':all_teacher, 'current_page':current_page, 'has_fav': has_fav, }) class OrgCourseView(View): """ Institutional Course List Page """ def get(self, request, org_id): current_page ='course' # Get the course institution according to id course_org = CourseOrg.objects.get(id = int(org_id)) # Find courses by course organization. Built-in variable, find the foreign key reference pointing to this field all_courses = course_org.course_set.all() # Judging the collection status has_fav = False if request.user.is_authenticated: if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2): has_fav = True return render(request,'org-detail-course.html',{ 'all_courses':all_courses, 'course_org': course_org, 'current_page':current_page, 'has_fav': has_fav, }) class OrgDescView(View): '''Organization Introduction Page''' def get(self, request, org_id): current_page ='desc' # Get the course institution according to id course_org = CourseOrg.objects.get(id = int(org_id)) # Judging the collection status has_fav = False if request.user.is_authenticated: if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2): has_fav = True return render(request,'org-detail-desc.html',{ 'course_org': course_org, 'current_page':current_page, 'has_fav': has_fav, }) class OrgTeacherView(View): """ Institutional Teacher Page """ def get(self, request, org_id): current_page ='teacher' course_org = CourseOrg.objects.get(id = int(org_id)) all_teacher = course_org.teacher_set.all() # Judging the collection status has_fav = False if request.user.is_authenticated: if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2): has_fav = True return render(request,'org-detail-teachers.html',{ 'all_teacher':all_teacher, 'course_org': course_org, 'current_page':current_page, 'has_fav': has_fav, }) class AddFavView(View): """ User favorites and unfavorites """ def post(self, request): fav_id = request.POST.get('fav_id', 0) # Prevent errors in the back int(fav_id) fav_type = request.POST.get('fav_type', 0) # Prevent int(fav_type) error if not request.user.is_authenticated: # When you are not logged in, return json to prompt you are not logged in. Jumping to the login page is done in ajax return HttpResponse('{"status":"fail", "msg":"User not logged in"}', content_type='application/json') exist_record = UserFavorite.objects.filter(user=request.user, fav_id=int(fav_id), fav_type=int(fav_type)) if exist_record: # If the record already exists, it means that the user unfavored exist_record.delete() return HttpResponse('{"status":"fail", "msg":"Uncollected"}', content_type='application/json') else: user_fav = UserFavorite() if int(fav_id)> 0 and int(fav_type)> 0: user_fav.user = request.user user_fav.fav_id = int(fav_id) user_fav.fav_type = int(fav_type) user_fav.save() return HttpResponse('{"status":"success", "msg":"Collection"}', content_type='application/json') else: return HttpResponse('{"status":"fail", "msg":"Collection error"}', content_type='application/json')
(5) Add judgment in org_base.html
(6) Modify the login and registration in the upper right corner
Put the login and registration judgments in the index.html page into org_base