Function Based View to Class Based View 3:24:02/3:45:40
AS USUAL,
1. startapp courses SET UP views.py
from django.shortcuts import render
# HTTP METHODS
def my_fbv(request, *args, **kwargs):
return render(request, ‘about.html’, {})
2. CREATE urls.py IN courses
from django.urls import path
from .views import (
my_fbv
)app_name=’courses’
urlpatterns = [
path(”, my_fbv, name=’courses-list’),
]
3. ADD THE APP INTO settings
4. ADD THE path IN urlpatterns INTO urls.py IN THE PROJECT
path(‘courses/’, include(‘courses.urls’)),
5. SETUP ONE FIELD IN models.py
from django.db import models
class Course(models.Model):
title = models.CharField(max_length=120)
NOW WE CHANGE TO CLASS BASED VIEW
IN views.py
from django.shortcuts import render
# To convert this to a class based biew we need to import View:
from django.views import View
# BASE VIEW Class = Viewclass CourseView(View):
template_name = “about.html”
def get(self, request, *args, **kwargs):
# GET method
return render(request, self.template_name, {})# def post(request, *args, **kwargs):
# return render(request, ‘about.html’, {})
# HTTP METHODS
def my_fbv(request, *args, **kwargs):
print(request.method)
return render(request, ‘about.html’, {})
IN urls.py
from django.urls import path
from .views import (
CourseView,
# my_fbv
)app_name=’courses’
urlpatterns = [
# path(”, my_fbv, name=’courses-list’),
path(”, CourseView.as_view(template_name=’base.html’),name=’courses-list’)
]
Raw Detail Class Based View 3:17:16
- ADD path(‘<int:id>/’, CourseView.as_view(), name=”courses-detail”), IN urls.py
from django.urls import path
from .views import (
CourseView,
# my_fbv
)app_name=’courses’
urlpatterns = [
# path(”, my_fbv, name=’courses-list’),
path(”, CourseView.as_view(template_name=’base.html’),name=’courses-list’),path(‘<int:id>/’, CourseView.as_view(), name=”courses-detail”),
]
2. IN views.py
ADD id=None IN THE CLASS CourseView(View):
CHANGE TEMPLATE NAME TO template_name = “courses/course_detail.html”
from django.shortcuts import render
# To convert this to a class based biew we need to import View:
from django.views import View
# BASE VIEW Class = Viewclass CourseView(View):
template_name = “courses/course_detail.html” #DetailView
def get(self, request, id=None, *args, **kwargs):
# GET method
return render(request, self.template_name, {})# def post(request, *args, **kwargs):
# return render(request, ‘about.html’, {})
# HTTP METHODS
def my_fbv(request, *args, **kwargs):
print(request.method)
return render(request, ‘about.html’, {})
3. SET UP NEW FOLDER /templates/courses/courses_detail.html
4. MAKE CHANGES AGIAN TO views.py
from django.shortcuts import render, get_object_or_404
# To convert this to a class based biew we need to import View:
from django.views import Viewfrom .models import Course
# BASE VIEW Class = Viewclass CourseView(View):
template_name = “courses/course_detail.html” #DetailView
def get(self, request, id=None, *args, **kwargs):
# GET method
context = {}
if id is not None:
obj = get_object_or_404(Course, id=id)
context[‘object’] = obj
return render(request, self.template_name, context)# def post(request, *args, **kwargs):
# return render(request, ‘about.html’, {})
# HTTP METHODS
def my_fbv(request, *args, **kwargs):
print(request.method)
return render(request, ‘about.html’, {})
Raw List Class Based View
MAKE CHANGES AGAIN TO views.py
class CourseListView(View):
template_name = “courses/course_list.html”
queryset = Course.objects.all()def get_queryset(self):
return self.queryset #go to change below contextdef get(self, request, *args, **kwargs):
# context = {‘object_list’: self.queryset}
context = {‘object_list’: self.get_queryset()}
return render(request, self.template_name, context)class MyListView(CourseListView):
# queryset = Course.objects.filter(id=1) #COULD ONLY SHOW ONE INSTANCE
queryset = Course.objects.all()
ACCORDINGLY REPLACE THE NEW VIEW WITH OLD VIEW IN urls.py
from django.urls import path
from .views import (
CourseView,
# CourseListView,
MyListView
# my_fbv
)app_name=’courses’
urlpatterns = [
# path(”, my_fbv, name=’courses-list’),
# path(”, CourseView.as_view(template_name=’base.html’),name=’courses-list’),
# path(”, CourseListView.as_view(),name=’courses-list’),
path(”, MyListView.as_view(),name=’courses-list’),path(‘<int:id>/’, CourseView.as_view(), name=”courses-detail”),
]
Raw Create Class Base View
- CREATE THE TEMPLATE HTML AND FORM IN FORMS
MAKE SURE YOU IMPORT THE FORM FROM FORMS IN views.py
from .forms import CourseModelForm
# BASE VIEW Class = Viewclass CourseCreateView(View):
template_name = “courses/course_create.html”
def get(self, request, *args, **kwargs):
# GET method
form = CourseModelForm()
context = {“form”: form}
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
# POST method
form = CourseModelForm(request.POST)
if form.is_valid():
form.save()
context = {“form”: form}
return render(request, self.template_name, context)
2. CREATE A NEW FILE forms.py
from django import forms
from .models import Course
class CourseModelForm(forms.ModelForm):
class Meta:
model = Course
fields = [
‘title’,
]
3. CREATE A NEW TEMPLATE courses/course_create.html
{% extends ‘base.html’ %}
{% block content %}
<form method=’POST’> {% csrf_token %}
{{ form.as_p }}
<input type=’submit’ value=’保存新资源’ />
</form>{% endblock %}
4. IMPORT CourseCreateView and ADD
path(‘create/’, CourseCreateView.as_view(),name=’courses-create’),
]
Raw Validation on a Post Method
from django import forms
from .models import Course
class CourseModelForm(forms.ModelForm):
class Meta:
model = Course
fields = [
‘title’,
]def clean_title(self):
title = self.cleaned_data.get(‘title’)
if title.lower()== ‘abc’:
raise forms.ValidationError(“输入内容无效”)
return title
FORM BECOMES CLEAN AFTER ENTRY:
def post(self, request, *args, **kwargs):
# POST method
form = CourseModelForm(request.POST)
if form.is_valid():
form.save()
form = CourseModelForm()
context = {“form”: form}
return render(request, self.template_name, context)
Raw Update Class Based View 3:38:38
UPDATE VIEW
class CourseUpdateView(View):
template_name=’courses/course_update.html’
obj = None
def get_object(self, **kwargs):
id = self.kwargs.get(‘id’)
if id is not None:
obj = get_object_or_404(Course, id=id)
return objdef get(self, request, id=None, *args, **kwargs):
# GET method
context = {}
obj = self.get_object()
if obj is not None:
form = CourseModelForm(instance=obj)
context[‘object’] = obj
context[‘form’] = form
return render(request, self.template_name, context)def post(self, request, id=None, *args, **kwargs):
# POST method
context = {}
obj = self.get_object()
if obj is not None:
form = CourseModelForm(request.POST,instance=obj)
if form.is_valid():
form.save()
context[‘object’] = obj
context[‘form’] = form
return render(request, self.template_name, context)
CREATE HTML TEMPLATE FOR UPDATE
<form action=’.’ method=’post’>{% csrf_token %}
{{ form.as_p }}
<input type = ‘submit’ value = ‘Save’ />
</form>
UPDATE URL
from. views import(
…
CourseUpdateView,
…
path(‘<int:id>/update/’, CourseUpdateView.as_view(),name=’courses-update’),
]
VS
(COMPARE ALL ABOVE WITH APP ARTICLE INCLUDING THE LAST SECTION BELOW:)
Raw Delete Class Based View
IMPORT redirect IN views.py AND DEFINE THE NEW CLASS – DELETE
from django.shortcuts import render, get_object_or_404,redirect
…
class CourseDeleteView(View):
template_name=’courses/course_delete.html’
def get_object(self):
id = self.kwargs.get(‘id’)
obj = None
if id is not None:
obj = get_object_or_404(Course, id=id)
return objdef get(self, request, id=None, *args, **kwargs):
# GET method
context = {}
obj = self.get_object()
if obj is not None:
context[‘object’] = obj
return render(request, self.template_name, context)def post(self, request, id=None, *args, **kwargs):
# POST method
context = {}
obj = self.get_object()
if obj is not None:
obj.delete()
context[‘object’] = None
return redirect(‘/courses/’)
return render(request, self.template_name, context)
CREATE courses/course_delete.html
{% extends ‘base.html’ %}
{% block content %}
<form action=’.’ method=’POST’>{% csrf_token %}
<h1>Do you want to delete the course “{{ object.title }}”?</h1>
<p><input type = ‘submit’ value = ‘Yes’ /> <a href = ‘../’>Cancel</a>
</p>
</form>{% endblock %}
ADD CourseDeleteView IN urls.py AND ADD:
path(‘<int:id>/delete/’, CourseDeleteView.as_view(),name=’courses-delete’),
]
CUSTOM MIXIN FOR CLASS BASED VIEWS (IN DELETE, UPDATE AND DETAIL VEIWS)
ADD A NEW MIXIN CLASS
class CourseObjectMixin(object):
# model = None
model = Course
# lookup = id
def get_object(self):
id = self.kwargs.get(‘id’)
# id = self.kwargs.get(self.lookup)
obj = None
if id is not None:
# obj = get_object_or_404(Course, id=id)
obj = get_object_or_404(self.model, id=id)
return obj
THEN WE GET GET RID OF get_object:
class CourseDeleteView(View):
# class CourseDeleteView(CourseObjectMixin,View): THEN WE CAN GET RID OF
# LINE 26-31
template_name=’courses/course_delete.html’
def get_object(self):
id = self.kwargs.get(‘id’)
obj = None
if id is not None:
obj = get_object_or_404(Course, id=id)
return obj
def get(self, request, id=None, *args, **kwargs):
# GET method
context = {}
obj = self.get_object()
if obj is not None:
context[‘object’] = obj
return render(request, self.template_name, context)def post(self, request, id=None, *args, **kwargs):
# POST method
context = {}
obj = self.get_object()
if obj is not None:
obj.delete()
context[‘object’] = None
return redirect(‘/courses/’)
return render(request, self.template_name, context)