Django REST API Backend Implementation Details
Session Management After Login
Upon successful authentication, the system generates a unique token string which is stored in the browser's cookies and also saved in the server-side session storage along with user identification.
Authentication Middleware Implementation
To enforce login protection for specific routes:
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
class AuthMiddleware(MiddlewareMixin):
def process_request(self, request):
# Skip authentication check for public pages
if request.path_info in ["/login/", "/image/code/"]:
return
# Check if user is logged in via session
user_info = request.session.get("info")
if user_info:
return
# Redirect unauthenticated users
return redirect('/login/')
Register the middleware in settings.py:
MIDDLEWARE = [
# ... other middleware
'myapp.middleware.auth.AuthMiddleware',
]
Form Handling with Validation
The form component handles HTML generation and data validation:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(
label="Username",
widget=forms.TextInput,
required=True
)
password = forms.CharField(
label="Password",
widget=forms.PasswordInput(render_value=True),
required=True
)
code = forms.CharField(
label="Verification Code",
widget=forms.TextInput,
required=True
)
def clean_password(self):
pwd = self.cleaned_data.get("password")
return md5(pwd)
Login view implementation:
from django.shortcuts import render, redirect
from django.contrib import messages
def login(request):
if request.method == "GET":
form = LoginForm()
return render(request, 'login.html', {'form': form})
form = LoginForm(data=request.POST)
if form.is_valid():
user_input_code = form.cleaned_data.pop('code')
stored_code = request.session.get('image_code', '')
if stored_code.upper() != user_input_code.upper():
form.add_error("code", "Invalid verification code")
return render(request, 'login.html', {'form': form})
user_obj = models.Admin.objects.filter(**form.cleaned_data).first()
if not user_obj:
form.add_error("password", "Invalid credentials")
return render(request, 'login.html', {'form': form})
# Store user session
request.session["info"] = {
'id': user_obj.id,
'name': user_obj.username
}
request.session.set_expiry(60 * 60 * 24 * 7)
return redirect("/admin/list/")
return render(request, 'login.html', {'form': form})
Template for Login Page
<div class="account">
<h2>Login</h2>
<form method="post" novalidate>
{% csrf_token %}
<div class="form-group">
<label>Username</label>
{{ form.username }}
<span style="color: red;">{{ form.username.errors.0 }}</span>
</div>
<div class="form-group">
<label>Password</label>
{{ form.password }}
<span style="color: red;">{{ form.password.errors.0 }}</span>
</div>
<div class="form-group">
<label>Verification Code</label>
<div class="row">
<div class="col-xs-7">
{{ form.code }}
<span style="color: red;">{{ form.code.errors.0 }}</span>
</div>
<div class="col-xs-5">
<img id="image_code" src="/image/code/" style="width: 125px;">
</div>
</div>
</div>
<input type="submit" value="Login" class="btn btn-primary">
</form>
</div>
ModelForm Usage
ModelForms simplify database operations:
class UserModelForm(forms.ModelForm):
name = forms.CharField(
min_length=3,
label="Name",
widget=forms.TextInput(attrs={"class": "form-control"})
)
class Meta:
model = models.UserInfo
fields = ["name", "password", "age", 'account', 'create_time', "gender", "depart"]
def user_model_form_add(request):
if request.method == "GET":
form = UserModelForm()
return render(request, 'user_model_form_add.html', {"form": form})
form = UserModelForm(data=request.POST)
if form.is_valid():
form.save()
return redirect('/user/list/')
return render(request, 'user_model_form_add.html', {"form": form})
Verification Code Hendling
Store verification codes in sessinos with timeout:
request.session['image_code'] = code_string
request.session.set_expiry(60)
Password Security
Password encryption using MD5 with secret key:
import hashlib
from django.conf import settings
def md5(data_string):
obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))
obj.update(data_string.encode('utf-8'))
return obj.hexdigest()
User Logout
Clear session data to terminate user session:
def logout(request):
request.session.clear()
return redirect('/login/')
Choice Field Display
For model fields with choices, use display methods:
# In model
gender_choices = ((1, "Male"),(2, "Female"),)
gender = models.SmallIntegerField(choices=gender_choices)
# In view or template
user = models.UserInfo.objects.first()
print(user.get_gender_display()) # Outputs: Male/Female
Caching Configuration
Configure caching backend:
CACHES = {
'default':{
'BACKEND':'django.core.cache.backends.locmem.LocMemCache',
'LOCATION':'unique-snowflake',
'TIMEOUT':300,
'OPTIONS':{
'MAX_ENTRIES':300,
'CULL_FREQUENCY':2,
}
}
}
Use cache decorator:
from django.views.decorators.cache import cache_page
@cache_page(15)
def test_cache(request):
import time
t = time.time()
return HttpResponse('time is %s'%(t))
Debugging with Traceback
Capture exception stack traces:
import traceback
try:
a
except:
print(traceback.format_exc())