django advanced more: https://docs.djangoproject.com/en/3.0/
Posted by Dakkar on Tue, 03 Mar 2020 08:46:59 +0100
Model
ORM (relationship object mapping)
1. field
AutoField(Field)
# int Auto increment column, parameter must be filled primary_key=True
BigAutoField(AutoField)
# bigint Auto increment column, parameter must be filled primary_key=True
//If there is no auto increment column in the model, a column named id will be created automatically
from django.db import models
class UserInfo(models.Model):
# Automatically create a column named id And is an increasing integer column
username = models.CharField(max_length=32)
class Group(models.Model):
# Custom Auto increment column
nid = models.AutoField(primary_key=True)
Self increasing field
SmallIntegerField(IntegerField):
# Small integer -32768 ~ 32767
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
# Positive small integer 0 ~ 32767
IntegerField(Field)
# Integer column(Signed) -2147483648 ~ 2147483647
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
# Positive integer 0 ~ 2147483647
BigIntegerField(IntegerField):
# Long integer(Signed) -9223372036854775808 ~ 9223372036854775807
# Custom unsigned integer field
class UnsignedIntegerField(models.IntegerField):
def db_type(self, connection):
return 'integer UNSIGNED'
Integer field
BooleanField(Field)
# Boolean type
NullBooleanField(Field):
# Boolean value that can be empty
CharField(Field)
# Character type
# Must provide max_length Parameters, max_length Represents character length
TextField(Field)
# Text type
EmailField(CharField):
# String type, Django Admin as well as ModelForm Authentication mechanism provided in
IPAddressField(Field)
# String type, Django Admin as well as ModelForm Validation provided in IPV4 mechanism
GenericIPAddressField(Field)
# String type, Django Admin as well as ModelForm Validation provided in Ipv4 and Ipv6
# Parameters:
protocol,Used for designation Ipv4 or Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, If specified as True,Then input.::ffff:192.0.2.1 It can be resolved to 192.0.2.1,To enable the stab function, you need to protocol="both"
URLField(CharField)
# String type, Django Admin as well as ModelForm Validation provided in URL
SlugField(CharField)
# String type, Django Admin as well as ModelForm Letters, numbers, underscores, connectors (minus signs) are supported for validation
CommaSeparatedIntegerField(CharField)
# String type, the format must be a comma separated number
UUIDField(Field)
# String type, Django Admin as well as ModelForm Provided in pairs UUID Format validation
FilePathField(Field)
# Character string, Django Admin as well as ModelForm The function of reading files under folders is provided in
# Parameters:
path, Folder path
match=None, Regular matching
recursive=False, Recurse the folder below
allow_files=True, Allow file
allow_folders=False, Allow folders
FileField(Field)
# String, path saved in database, file uploaded to specified directory
# Parameters:
upload_to = "" Save path of uploaded file
storage = None Storage components, default django.core.files.storage.FileSystemStorage
ImageField(FileField)
# String, path saved in database, file uploaded to specified directory
# Parameters:
upload_to = "" Save path of uploaded file
storage = None Storage components, default django.core.files.storage.FileSystemStorage
width_field=None, Highly saved database field name (string) of uploaded image
height_field=None Width of uploaded image saved database field name (string)
DateTimeField(DateField)
# date+Time format YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField(DateTimeCheckMixin, Field)
# Date format YYYY-MM-DD
TimeField(DateTimeCheckMixin, Field)
# Time format HH:MM[:ss[.uuuuuu]]
DurationField(Field)
# Long integer, time interval, according to bigint Storage, ORM The value obtained in is datetime.timedelta type
FloatField(Field)
# float
DecimalField(Field)
# 10 Binary decimal system
# Parameters:
max_digits,Total decimal length
decimal_places,Decimal length
BinaryField(Field)
# Binary type
Other fields
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'UUIDField': 'char(32)',
The return value is the property of the field in the database, and the default value of Django field
null Whether the field in the database can be empty
db_column Column name of the field in the database
db_tablespace
default Default values for fields in the database
primary_key Whether the fields in the database are primary keys
db_index Whether fields in the database can be indexed
unique Whether fields in the database can be uniquely indexed
unique_for_date Can a unique index be created for the date part of the field in the database
unique_for_month Can a unique index be created for the [month] part of the field in the database
unique_for_year Can a unique index be created for the year part of the field in the database
verbose_name Admin Field name shown in
blank Admin Allow user input to be blank in
editable Admin Whether it can be edited in
help_text Admin Prompt for this field in
choices Admin The contents of the selection box are displayed in, and unchanging data is placed in memory to avoid cross table operation
//Such as: gf = models.IntegerField(choices=[(0, 'xx'),(1, 'xxx'),],default=1)
error_messages Customize the error information (Dictionary type), so as to customize the error information to be displayed;
//Dictionary key: null, blank, invalid, invalid_choice, unique, and unique_for_date
//{'null': "Can not be empty.", 'invalid': 'Format error'}
validators Customize error validation (list type) to customize the validation rules you want
from django.core.validators import RegexValidator
from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
//Such as:
test = models.CharField(
max_length=32,
error_messages={
'c1': 'Priority error message 1',
'c2': 'Priority error message 2',
'c3': 'Priority error message 3',
},
validators=[
RegexValidator(regex='root_\d+', message='Wrong.', code='c1'),
RegexValidator(regex='root_112233\d+', message='Wrong again.', code='c2'),
EmailValidator(message='Wrong again.', code='c3'), ]
parameter
# Table names generated in the database default app Name + Underline + Class name
db_table = "table_name"
# Joint index
index_together = [
("pub_date", "deadline"),
]
# Union unique index
unique_together = (("driver", "restaurant"),)
# admin Table name shown in
verbose_name
# verbose_name plus s
verbose_name_plural
//More: https://docs.djangoproject.com/en/1.10/ref/models/options/
class Meta:
a. Django Admin The error messages in will take precedence according to Admiin Internal ModelForm Error message prompt, if all succeed, check Model And displays the specified error message
b. call Model Object clean_fields Methods, such as:
# models.py
class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
username = models.CharField(max_length=32)
email = models.EmailField(error_messages={'invalid': 'The format is wrong..'})
# views.py
def index(request):
obj = models.UserInfo(username='11234', email='uu')
try:
print(obj.clean_fields())
except Exception as e:
print(e)
return HttpResponse('ok')
# Model Of clean Method is a hook that can be used for custom operations, such as exception handling above.
Trigger validation and error prompts in the Model
# admin.py
from django.contrib import admin
from model_club import models
from django import forms
class UserInfoForm(forms.ModelForm):
username = forms.CharField(error_messages={'required': 'User name cannot be empty.'})
email = forms.EmailField(error_messages={'invalid': 'Mailbox format error.'})
age = forms.IntegerField(initial=1, error_messages={'required': 'Please enter a value.', 'invalid': 'Age must be numeric.'})
class Meta:
model = models.UserInfo
# fields = ('username',)
fields = "__all__"
class UserInfoAdmin(admin.ModelAdmin):
form = UserInfoForm
admin.site.register(models.UserInfo, UserInfoAdmin)
Modify error prompt in admin
2. continuous tables
- One to many: models.foreignkey (other tables)
- Many to many: models.manytomanyfield (other tables)
- One to one: models.onetoonefield (other tables)
ForeignKey(ForeignObject) # ForeignObject(RelatedField)
to, # Table name to associate
to_field=None, # Field name in the table to associate
on_delete=None, # The behavior of the current table and its associated rows when data in the associated table is deleted
- models.CASCADE,Delete associated data and associated data
- models.DO_NOTHING,Delete associated data, error raised IntegrityError
- models.PROTECT,Delete associated data, error raised ProtectedError
- models.SET_NULL,Delete the associated data with the value set to null(premise FK Field needs to be set to nullable)
- models.SET_DEFAULT,Delete the associated data, and set the value associated with it to the default value (premise FK Field needs to set default value)
- models.SET,Delete associated data,
a. The associated value is set to the specified value, setting: models.SET(value)
b. The value associated with it is set to the return value of the executable object. Set: models.SET(Executable object)
def func():
return 10
class MyModel(models.Model):
user = models.ForeignKey(
to="User",
to_field="id"
on_delete=models.SET(func),)
related_name=None, # In reverse operation, the field name is used instead of table name_set] Such as: obj.Table name_set.all()
related_query_name=None, # In reverse operation, the connection prefix is used to replace table name Such as: models.UserGroup.objects.filter(Table name__Field name=1).values('Table name__Field name')
limit_choices_to=None, # stay Admin or ModelForm When the associated data is displayed in, the following conditions are provided:
# Such as:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}
from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
db_constraint=True # Whether to create a foreign key constraint in the database
parent_link=False # stay Admin Show associated data in
OneToOneField(ForeignKey)
to, # Table name to associate
to_field=None # Field name in the table to associate
on_delete=None, # The behavior of the current table and its associated rows when data in the associated table is deleted
###### For one-on-one ######
# 1. One to one is actually one to many + unique index
# 2.When there is an inheritance relationship between two classes, a one-to-one field will be created by default
# The following will be A Add an additional one to the table c_ptr_id Column and unique:
class C(models.Model):
nid = models.AutoField(primary_key=True)
part = models.CharField(max_length=12)
class A(C):
id = models.AutoField(primary_key=True)
code = models.CharField(max_length=1)
ManyToManyField(RelatedField)
to, # Table name to associate
related_name=None, # In reverse operation, the field name is used instead of table name_set] Such as: obj.Table name_set.all()
related_query_name=None, # In reverse operation, the connection prefix is used to replace table name Such as: models.UserGroup.objects.filter(Table name__Field name=1).values('Table name__Field name')
limit_choices_to=None, # stay Admin or ModelForm When the associated data is displayed in, the following conditions are provided:
# Such as:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}
from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
symmetrical=None, # For many to many self association only, symmetrical A field that specifies whether a reverse operation is created internally
# When doing the following operations, the symmetrical There will be different optional fields
models.BB.objects.filter(...)
# The optional fields are: code, id, m1
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=True)
# Optional fields are: bb, code, id, m1
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=False)
through=None, # Use fields to specify relational tables when customizing the third table
through_fields=None, # When customizing the third table, use fields to specify which fields in the relationship table are used for many to many relationship tables
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
)
class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
inviter = models.ForeignKey(
Person,
on_delete=models.CASCADE,
related_name="membership_invites",
)
invite_reason = models.CharField(max_length=64)
db_constraint=True, # Whether to create a foreign key constraint in the database
db_table=None, # The name of the table in the database when the third table is created by default
Fields, parameters
3. operation
# increase
# models.Tb1.objects.create(c1='xx', c2='oo') Add a piece of data to accept dictionary type data **kwargs
# obj = models.Tb1(c1='xx', c2='oo')
# obj.save()
# check
# models.Tb1.objects.get(id=123) # Get a single piece of data and report an error if it does not exist (not recommended)
# models.Tb1.objects.all() # Get all
# models.Tb1.objects.filter(name='seven') # Get data for the specified condition
# Delete
# models.Tb1.objects.filter(name='seven').delete() # Delete data for specified conditions
# change
# models.Tb1.objects.filter(name='seven').update(gender='0') # Update the data of the specified conditions, all of which support * * kwargs
# obj = models.Tb1.objects.get(id=1)
# obj.c1 = '111'
# obj.save() # Modify single data
basic operation
# Get number
#
# models.Tb1.objects.filter(name='seven').count()
# Greater than, less than
#
# models.Tb1.objects.filter(id__gt=1) # Get a value with id greater than 1
# models.Tb1.objects.filter(id__gte=1) # Get a value with id greater than or equal to 1
# models.Tb1.objects.filter(id__lt=10) # Get a value with id less than 10
# models.Tb1.objects.filter(id__lte=10) # Get a value with id less than 10
# models.Tb1.objects.filter(id__lt=10, id__gt=1) # Get a value with id greater than 1 and less than 10
# in
#
# models.Tb1.objects.filter(id__in=[11, 22, 33]) # Get data with id equal to 11, 22, 33
# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
# isnull
# Entry.objects.filter(pub_date__isnull=True)
# contains
#
# models.Tb1.objects.filter(name__contains="ven")
# models.Tb1.objects.filter(name__icontains="ven") # icontains case insensitive
# models.Tb1.objects.exclude(name__icontains="ven")
# range
#
# models.Tb1.objects.filter(id__range=[1, 2]) # Range between and
# Other similar
#
# startswith,istartswith, endswith, iendswith,
# order by
#
# models.Tb1.objects.filter(name='seven').order_by('id') # asc
# models.Tb1.objects.filter(name='seven').order_by('-id') # desc
# group by
#
# from django.db.models import Count, Min, Max, Sum
# models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
# limit ,offset
#
# models.Tb1.objects.all()[10:20]
# regex Regular matching, iregex Case insensitive
#
# Entry.objects.get(title__regex=r'^(An?|The) +')
# Entry.objects.get(title__iregex=r'^(an?|the) +')
# date
#
# Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
# Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
# year
#
# Entry.objects.filter(pub_date__year=2005)
# Entry.objects.filter(pub_date__year__gte=2005)
# month
#
# Entry.objects.filter(pub_date__month=12)
# Entry.objects.filter(pub_date__month__gte=6)
# day
#
# Entry.objects.filter(pub_date__day=3)
# Entry.objects.filter(pub_date__day__gte=3)
# week_day
#
# Entry.objects.filter(pub_date__week_day=2)
# Entry.objects.filter(pub_date__week_day__gte=2)
# hour
#
# Event.objects.filter(timestamp__hour=23)
# Event.objects.filter(time__hour=5)
# Event.objects.filter(timestamp__hour__gte=12)
# minute
#
# Event.objects.filter(timestamp__minute=29)
# Event.objects.filter(time__minute=46)
# Event.objects.filter(timestamp__minute__gte=29)
# second
#
# Event.objects.filter(timestamp__second=31)
# Event.objects.filter(time__second=2)
# Event.objects.filter(timestamp__second__gte=31)
Advanced operation (double underline)
# extra
#
# extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
# Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
# Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
# Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
# Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
# F
#
# from django.db.models import F
# models.Tb1.objects.update(num=F('num')+1)
# Q
#
# Method 1:
# Q(nid__gt=10)
# Q(nid=8) | Q(nid__gt=10)
# Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
# Mode two:
# con = Q()
# q1 = Q()
# q1.connector = 'OR'
# q1.children.append(('id', 1))
# q1.children.append(('id', 10))
# q1.children.append(('id', 9))
# q2 = Q()
# q2.connector = 'OR'
# q2.children.append(('c1', 1))
# q2.children.append(('c1', 10))
# q2.children.append(('c1', 9))
# con.add(q1, 'AND')
# con.add(q2, 'AND')
#
# models.Tb1.objects.filter(con)
# Execution primordial SQL
#
# from django.db import connection, connections
# cursor = connection.cursor() # cursor = connections['default'].cursor()
# cursor.execute("""SELECT * from auth_user where id = %s""", [1])
# row = cursor.fetchone()
extra,F,Q,python native sql
# Table structure instance oto and fk Medium demand addition on_delete The code above the parameter contains
class UserProfile(models.Model):
user_info = models.OneToOneField('UserInfo',on_delete=models.CASCADE)
username = models.CharField(max_length=64)
password = models.CharField(max_length=64)
def __str__(self):
return self.username
class UserInfo(models.Model):
user_type_choice = (
(0, u'Ordinary users'),
(1, u'Advanced user'),
)
user_type = models.IntegerField(choices=user_type_choice)
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
address = models.CharField(max_length=128)
def __str__(self):
return self.name
class UserGroup(models.Model):
caption = models.CharField(max_length=64)
user_info = models.ManyToManyField('UserInfo')
def __str__(self):
return self.caption
class Host(models.Model):
hostname = models.CharField(max_length=64)
ip = models.GenericIPAddressField()
user_group = models.ForeignKey('UserGroup',on_delete=models.CASCADE)
def __str__(self):
return self.hostname
Table structure
#o2o
user_info_obj = models.UserInfo.objects.filter(id=1).first()
print user_info_obj.user_type
print user_info_obj.get_user_type_display()
print user_info_obj.userprofile.password
user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
print user_info_obj.keys()
print user_info_obj.values()
#m2o
//Similar to one-on-one
1,Search criteria use __ Connect
2,Use when getting values . Connect
#m2m
user_info_obj = models.UserInfo.objects.get(name='xxx')
user_info_objs = models.UserInfo.objects.all()
group_obj = models.UserGroup.objects.get(caption='xxxx')
group_objs = models.UserGroup.objects.all()
# Add data
#group_obj.user_info.add(user_info_obj)
#group_obj.user_info.add(*user_info_objs)
# Delete data
#group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)
# Add data
#user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs)
# Delete data
#user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs)
# get data
#print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)
# get data
#print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CEO')
#print user_info_obj.usergroup_set.all().filter(caption='DBA')
Linked list
form
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from django import forms
from django.core.exceptions import ValidationError
def mobile_validate(value):
mobile_re = re.compile('^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(value):
raise ValidationError('Mobile number format error')
class PublishForm(forms.Form):
user_type_choice = (
(0, 'Ordinary users'),
(1, 'Advanced user'),
)
user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,
attrs={'class': "form-control"}))
title = forms.CharField(max_length=20,
min_length=5,
error_messages={'required': 'Title cannot be empty',
'min_length': 'The title must be at least 5 characters',
'max_length': 'Title up to 20 characters'},
widget=forms.TextInput(attrs={'class': "form-control",
'placeholder': 'Heading 5-20 Character'}))
memo = forms.CharField(required=False,
max_length=256,
widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': 'Detailed description', 'rows': 3}))
phone = forms.CharField(validators=[mobile_validate, ],
error_messages={'required': 'Mobile phone cannot be empty'},
widget=forms.TextInput(attrs={'class': "form-control",
'placeholder': 'Phone number'}))
email = forms.EmailField(required=False,
error_messages={'required': 'Mailbox cannot be empty','invalid': 'Mailbox format error'},
widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': 'mailbox'}))
Define form form
def publish(request):
ret = {'status': False, 'data': '', 'error': '', 'summary': ''}
if request.method == 'POST':
request_form = PublishForm(request.POST)
if request_form.is_valid():
request_dict = request_form.clean()
print(request_dict)
ret['status'] = True
else:
error_msg = request_form.errors.as_json()
#as_ul(), as_text()
ret['error'] = json.loads(error_msg)
return HttpResponse(json.dumps(ret))
views verification
class AdminModelForm(forms.ModelForm):
class Meta:
model = models.Admin
#fields = '__all__'
fields = ('username', 'email')
widgets = {
'email' : forms.PasswordInput(attrs={'class':"xxx"}),
}
modelform validation
Cross-site request forgery
Django implements the function of preventing cross Site Request Forgery for users through middleware django.middleware.csrf.CsrfViewMiddleware. The anti Cross Station Request Forgery function in Django can be divided into global and local.
Overall situation:
Middleware django.middleware.csrf.csfviewmiddleware
Part:
- @CSRF? Protect, which forces to set the anti Cross Site Request Forgery function for the current function, even if the global middleware is not set in the settings.
- @csrf_exempt, cancel the current function anti Cross Site Request Forgery function, even if the global middleware is set in settings.
from django.views.decorators.csrf import csrf_exempt,csrf_protect
veiws Set the return value in:
return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))
//perhaps
return render(request, 'xxx.html', data)
html Set in Token:
{% csrf_token %}
General form
# Establish js Document, following
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
let csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
# Use ajax
<script src='Above file name xxx.js'></script>
<script>
.....
</script>
ajax
more:https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
Cookies and session s
Acquisition of Chinese Medicine
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
Parameters:
Default: default
Salt: salt addition
Max? Age: background control expiration time
Setting up
rep = HttpResponse(...) or rep = render(request,...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt = 'encrypted salt',...)
Parameters:
Key, key
Value = '', value
max_age=None, timeout
expires=None, timeout (ie requires expires, so set it if has't been already ready.)
Path = '/', the path where the cookie takes effect, / indicates the root path, special: the cookie following the path can be accessed by any url page
Domain = none, the domain name in which the cookie takes effect
Secure = false, HTTPS transport
httponly=False can only be transmitted by http protocol and cannot be obtained by JavaScript (not absolute, the underlying packet grabbing can be obtained or overwritten)
#The cookie is saved on the client side. The native js and jQuery are operable
<script src='/static/js/jquery-3.4.1.js'></script>
$.cookie("list_pager_num", 30,{ path: '/' });
cookie
'''
Django Default support in Session,There are five types of Session For developers:
//Database (default)
//cache
//file
//Cache + Database
//Encrypted cookie
'''
# data base session
Django Default support Session,And the default is Session Data is stored in the database, that is: django_session In the table.
a. To configure settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # Engine (default)
SESSION_COOKIE_NAME = "sessionid" # Session Of cookie When saved on the browser key,Namely: sessionid=Random string (default)
SESSION_COOKIE_PATH = "/" # Session Of cookie Saved path (default)
SESSION_COOKIE_DOMAIN = None # Session Of cookie Saved domain name (default)
SESSION_COOKIE_SECURE = False # Whether Https transmission cookie(Default)
SESSION_COOKIE_HTTPONLY = True # Whether Session Of cookie Only support http Transfer (default)
SESSION_COOKIE_AGE = 1209600 # Session Of cookie Expiration date (2 weeks) (default)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Whether to close the browser Session Expiration (default)
SESSION_SAVE_EVERY_REQUEST = False # Save every request Session,Save after default modification (default)
b. Use
def index(request):
# Get, set, delete Session Middle data
request.session['k1']
request.session.get('k1',None)
request.session['k1'] = 123
request.session.setdefault('k1',123) # Do not set if it exists
del request.session['k1']
# All key, value, key value pairs
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()
# user session Random string of
request.session.session_key
# Will all Session Delete data with expiration date less than current date
request.session.clear_expired()
# Check users session Is the random string of
request.session.exists("session_key")
# Delete all of the current user's Session data
request.session.delete("session_key")
request.session.set_expiry(value)
* If value It's an integer, session It will expire in a few seconds.
* If value It's a datatime or timedelta,session It will expire after this time.
* If value It's 0.,User closes browser session It will fail.
* If value yes None,session Will depend on the overall situation session Failure strategy.
# cache session
a. To configure settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # engine
SESSION_CACHE_ALIAS = 'default' # Cache alias used (default memory cache, or memcache),Alias depends on cached settings here
SESSION_COOKIE_NAME = "sessionid" # Session Of cookie When saved on the browser key,Namely: sessionid=Random string
SESSION_COOKIE_PATH = "/" # Session Of cookie Saved path
SESSION_COOKIE_DOMAIN = None # Session Of cookie Saved domain name
SESSION_COOKIE_SECURE = False # Whether Https transmission cookie
SESSION_COOKIE_HTTPONLY = True # Whether Session Of cookie Only support http transmission
SESSION_COOKIE_AGE = 1209600 # Session Of cookie Expiration date (2 weeks)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Whether to close the browser Session Be overdue
SESSION_SAVE_EVERY_REQUEST = False # Save every request Session,Save only after default modification
b. Use
//Ditto
# file session
a. To configure settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # engine
SESSION_FILE_PATH = None # Cache file path, if None,Then use tempfile Module gets a temporary address tempfile.gettempdir() # For example, / var / folders / D3 / j9tj0gz93dg06bmwxmhh6 xm0000gn / T
SESSION_COOKIE_NAME = "sessionid" # Session Of cookie When saved on the browser key,Namely: sessionid=Random string
SESSION_COOKIE_PATH = "/" # Session Of cookie Saved path
SESSION_COOKIE_DOMAIN = None # Session Of cookie Saved domain name
SESSION_COOKIE_SECURE = False # Whether Https transmission cookie
SESSION_COOKIE_HTTPONLY = True # Whether Session Of cookie Only support http transmission
SESSION_COOKIE_AGE = 1209600 # Session Of cookie Expiration date (2 weeks)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Whether to close the browser Session Be overdue
SESSION_SAVE_EVERY_REQUEST = False # Save every request Session,Save only after default modification
b. Use
//Ditto
# cache+data base session
Database is used for persistence and cache is used for efficiency improvement
a. To configure settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # engine
b. Use
//Ditto
# encryption cookie
a. To configure settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # engine
b. Use
//Ditto
# session User authentication decorator
def login(func):
def wrap(request, *args, **kwargs):
# If not logged in, jump to the specified page
if request.path == '/test/':
return redirect('http://xxxxxxxxxxxx')
return func(request, *args, **kwargs)
return wrap
session
paging
# version 1
views.py
from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
L = []
for i in range(999):
L.append(i)
def index(request):
current_page = request.GET.get('p')
paginator = Paginator(L, 10)
# per_page: Number of entries per page
# count: Total number of data
# num_pages:PageCount
# page_range:Index range of total pages, such as: (1,10),(1,200)
# page: page object
try:
posts = paginator.page(current_page)
# has_next Is there a next page
# next_page_number Next page
# has_previous Is there a previous page
# previous_page_number Previous page
# object_list List of data after paging
# number Current page
# paginator paginator object
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
return render(request, 'index.html', {'posts': posts})
HTML
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul>
{% for item in posts %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<div class="pagination">
<span class="step-links">
{% if posts.has_previous %}
<a href="?p={{ posts.previous_page_number }}">Previous</a>
{% endif %}
<span class="current">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
</span>
{% if posts.has_next %}
<a href="?p={{ posts.next_page_number }}">Next</a>
{% endif %}
</span>
</div>
</body>
</html>
#version 2
views.py
from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
class CustomPaginator(Paginator):
def __init__(self, current_page, max_pager_num, *args, **kwargs):
"""
:param current_page: Current page
:param max_pager_num:Maximum number of pages displayed
:param args:
:param kwargs:
:return:
"""
self.current_page = int(current_page)
self.max_pager_num = max_pager_num
super(CustomPaginator, self).__init__(*args, **kwargs)
def page_num_range(self):
# Current page
# self.current_page
# PageCount
# self.num_pages
# Maximum number of pages displayed
# self.max_pager_num
print(1)
if self.num_pages < self.max_pager_num:
return range(1, self.num_pages + 1)
print(2)
part = int(self.max_pager_num / 2)
if self.current_page - part < 1:
return range(1, self.max_pager_num + 1)
print(3)
if self.current_page + part > self.num_pages:
return range(self.num_pages + 1 - self.max_pager_num, self.num_pages + 1)
print(4)
return range(self.current_page - part, self.current_page + part + 1)
L = []
for i in range(999):
L.append(i)
def index(request):
current_page = request.GET.get('p')
paginator = CustomPaginator(current_page, 11, L, 10)
# per_page: Number of entries per page
# count: Total number of data
# num_pages:PageCount
# page_range:Index range of total pages, such as: (1,10),(1,200)
# page: page object
try:
posts = paginator.page(current_page)
# has_next Is there a next page
# next_page_number Next page
# has_previous Is there a previous page
# previous_page_number Previous page
# object_list List of data after paging
# number Current page
# paginator paginator object
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
return render(request, 'index.html', {'posts': posts})
HTML
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul>
{% for item in posts %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<div class="pagination">
<span class="step-links">
{% if posts.has_previous %}
<a href="?p={{ posts.previous_page_number }}">Previous</a>
{% endif %}
{% for i in posts.paginator.page_num_range %}
<a href="?p={{ i }}">{{ i }}</a>
{% endfor %}
{% if posts.has_next %}
<a href="?p={{ posts.next_page_number }}">Next</a>
{% endif %}
</span>
<span class="current">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
</span>
</div>
</body>
</html>
Built-in paging
'''
//Paging function is necessary in every website. For paging, it is actually to calculate the starting position in the database table according to the user's input.
1,Set the number of data displayed per page
2,User input page number (Page 1, page 2...)
3,Calculate the starting position of the data table to be fetched according to the set number of displayed items and the current page number
4,In the data table, the value is taken according to the starting position, and the data is output on the page
//The demand is coming again. You need to display the paged page on the page. If: [previous] [1] [2] [3] [4] [5] [next]
1,Set the number of data displayed per page
2,User input page number (Page 1, page 2...)
3,Set how many page numbers are displayed
4,Get the total number of current data
5,Calculate the total number of pages according to the number of pages displayed and the total number of data
6,Calculate the starting position of the data table to be fetched according to the set number of displayed items and the current page number
7,In the data table, the value is taken according to the starting position, and the data is output on the page
8,Output paging html,Such as:[Previous page][1][2][3][4][5][next page]
'''
#!/usr/bin/env python
# _*_coding:utf-8_*_
from django.utils.safestring import mark_safe
class PageInfo(object):
def __init__(self,current,totalItem,peritems=5):
self.__current=current
self.__peritems=peritems
self.__totalItem=totalItem
def From(self):
return (self.__current-1)*self.__peritems
def To(self):
return self.__current*self.__peritems
def TotalPage(self): #PageCount
result=divmod(self.__totalItem,self.__peritems)
if result[1]==0:
return result[0]
else:
return result[0]+1
def Custompager(baseurl,currentPage,totalpage): #Base page, current page, total pages
perPager=11
#PageCount<11
#0 -- totalpage
#PageCount>11
#Current page is greater than 5 currentPage-5 -- currentPage+5
#currentPage+5 Whether the total number of pages is exceeded,More than total pages, end Is the total number of pages
#Current page is less than 50 -- 11
begin=0
end=0
if totalpage <= 11:
begin=0
end=totalpage
else:
if currentPage>5:
begin=currentPage-5
end=currentPage+5
if end > totalpage:
end=totalpage
else:
begin=0
end=11
pager_list=[]
if currentPage<=1:
first="<a href=''>home page</a>"
else:
first="<a href='%s%d'>home page</a>" % (baseurl,1)
pager_list.append(first)
if currentPage<=1:
prev="<a href=''>Previous page</a>"
else:
prev="<a href='%s%d'>Previous page</a>" % (baseurl,currentPage-1)
pager_list.append(prev)
for i in range(begin+1,end+1):
if i == currentPage:
temp="<a href='%s%d' class='selected'>%d</a>" % (baseurl,i,i)
else:
temp="<a href='%s%d'>%d</a>" % (baseurl,i,i)
pager_list.append(temp)
if currentPage>=totalpage:
next="<a href='#'>next page</a>"
else:
next="<a href='%s%d'>next page</a>" % (baseurl,currentPage+1)
pager_list.append(next)
if currentPage>=totalpage:
last="<a href=''>Last</a>"
else:
last="<a href='%s%d'>Last</a>" % (baseurl,totalpage)
pager_list.append(last)
result=''.join(pager_list)
return mark_safe(result) #Convert string to html language
'''
//In summary, there are three things to do when paging:
//Create a class to process paging data
//Get data from paging data
//Output page HTML, that is: [previous] [1] [2] [3] [4] [5] [next]
'''
custom
There are many plug-ins on the Internet. Search them out and have a look
cache
As Django is a dynamic website, all requests will go to the data for corresponding operations. When the program has a large amount of visits, the time-consuming will be more obvious. The simplest solution is to use: cache, which saves the return value of a certain view to memory or memcache. When someone comes to visit in 5 minutes, the operation in view will not be performed, but directly from the The previously cached content in the stored or Redis is retrieved and returned.
There are six caching methods available in Django:
- Development and commissioning
- Memory
- file
- data base
- Memcache cache (Python memcached module)
- Memcache cache (pylibmc module)
# This is the start of commissioning. No internal operation is required
# To configure:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # engine
'TIMEOUT': 300, # Cache timeout (default 300, None Indicates never expires, 0 indicates immediate expiration)
'OPTIONS':{
'MAX_ENTRIES': 300, # Maximum number of caches (300 by default)
'CULL_FREQUENCY': 3, # After the maximum number of caches is reached, the proportion of the number of caches to be eliminated is: 1/CULL_FREQUENCY(Default 3)
},
'KEY_PREFIX': '', # cache key Prefix for (default empty)
'VERSION': 1, # cache key Version of (default 1)
'KEY_FUNCTION' Function name # generate key Function of (the default function will be generated as::Edition:key])
}
}
# custom key
def default_key_func(key, key_prefix, version):
"""
Default function to generate keys.
Constructs the key used by all other methods. By default it prepends
the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
function with custom key making behavior.
"""
return '%s:%s:%s' % (key_prefix, version, key)
def get_key_func(key_func):
"""
Function to decide which key function to use.
Defaults to ``default_key_func``.
"""
if key_func is not None:
if callable(key_func):
return key_func
else:
return import_string(key_func)
return default_key_func
Development and commissioning
# This cache saves content to variables in memory
# To configure:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
# Other configurations are the same as the development debugging version
Memory
# This cache saves content to a file
# To configure:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}
# Other configurations are the same as the development debugging version
file
# This cache saves content to the database
# To configure:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # Database table
}
}
# Execute create table command python manage.py createcachetable
data base
# This cache uses python-memcached Module connection memcache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'unix:/tmp/memcached.sock',
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
Memcache cache (Python memcached module)
# This cache uses pylibmc Module connection memcache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '127.0.0.1:11211',
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '/tmp/memcached.sock',
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
Memcache cache (pylibmc module)
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
# "PASSWORD": "Password",
}
}
}
Redis cache (dependency: PIP3 install Django redis)
from django_redis import get_redis_connection
conn = get_redis_connection("default")
Connection operation in views
#Total station
Use middleware, through a series of authentication and other operations, if the content exists in the cache, use FetchFromCacheMiddleware Get the content and return it to the user. Before returning it to the user, judge whether the cache already exists. If not, then UpdateCacheMiddleware The cache will be saved to the cache to realize the whole site cache
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
# Other Middleware ...
'django.middleware.cache.FetchFromCacheMiddleware',
]
CACHE_MIDDLEWARE_ALIAS = ""
CACHE_MIDDLEWARE_SECONDS = ""
CACHE_MIDDLEWARE_KEY_PREFIX = ""
#Separate view
Method 1:
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
...
//Mode two:
from django.views.decorators.cache import cache_page
urlpatterns = [
url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
]
#Partial view
a. Introduce TemplateTag
{% load cache %}
b. Using caching
{% cache 5000 cache key %}
//Cache content
{% endcache %}
application
serialize
'''
//The serialization in Django is mainly used to return the data retrieved in the database to the client user, and the special Ajax request is usually returned in Json format.
'''
# serializers
from django.core import serializers
ret = models.BookType.objects.all()
data = serializers.serialize("json", ret)
# json.dumps
import json
#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption')
ret=list(ret)
result = json.dumps(ret)
'''
//Because the datetime date cannot be processed in json.dumps, you can extend it by customizing the processor
'''
import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field, datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(field, date):
return o.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, field)
# ds = json.dumps(d, cls=JsonCustomEncoder)
signal
Django provides "signal scheduling" for decoupling when the framework performs operations. Generally speaking, when some actions occur, the signal allows the specific sender to remind some receivers.
Model signals
pre_init # django Of modal Trigger automatically before executing its construction method
post_init # django Of modal Triggered automatically after execution of its construction method
pre_save # django Of modal Automatically triggered before saving an object
post_save # django Of modal Automatically triggered when an object is saved
pre_delete # django Of modal Auto trigger before object deletion
post_delete # django Of modal Triggered automatically when an object is deleted
m2m_changed # django Of modal Use in m2m Third table of field operation( add,remove,clear)Front and rear, automatic trigger
class_prepared # Detect registered app in modal Class, for each class, auto trigger
Management signals
pre_migrate # implement migrate Auto trigger before command
post_migrate # implement migrate Automatically triggered after command
Request/response signals
request_started # Auto trigger before request
request_finished # Auto trigger after request
got_request_exception # Automatically triggered after request exception
Test signals
setting_changed # Use test Triggered automatically when a profile is modified by a test
template_rendered # Use test Automatically triggered when testing a render template
Database Wrappers
connection_created # Automatically triggered when creating a database connection
Built-in signal
#about Django The built-in signal only needs to register the specified signal. When the program performs the corresponding operation, the registration function will be triggered automatically
from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception
from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate
from django.test.signals import setting_changed
from django.test.signals import template_rendered
from django.db.backends.signals import connection_created
def callback(sender, **kwargs):
print("xxoo_callback")
print(sender,kwargs)
xxoo.connect(callback)
# xxoo Refers to the content imported above
from django.core.signals import request_finished
from django.dispatch import receiver
@receiver(request_finished)
def my_callback(sender, **kwargs):
print("Request finished!")
Use built-in signal
# Definition
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
# register
def callback(sender, **kwargs):
print("callback")
print(sender,kwargs)
pizza_done.connect(callback)
# trigger
from Route import pizza_done
pizza_done.send(sender='seven',toppings=123, size=456)
# Because the trigger of the built-in signal has been integrated into Django , so it will be called automatically, and for the custom signal, the developer needs to trigger it anywhere.
Custom signal
Topics:
Python
Django
Session
Database
JSON