Page
view layer
def fenye(request): all_data = models.AuthorDetail.objects.all() current_page = request.GET.get('page',1) count = all_data.count() page_obj = Pagination(current_page=current_page,all_count=count) data = all_data[page_obj.start:page_obj.end] return render(request,'fenye.html',locals())
Template layer
{% for a in data %} <p>{<!-- -->{ a.addr }}</p> {% endfor %} {<!-- -->{ page_obj.page_html|safe }}
Custom paginator
class Pagination(object): def __init__(self, current_page, all_count, per_page_num=10, pager_count=11): """ Encapsulate paging related data :param current_page: current page :param all_count: The total number of data in the database :param per_page_num: The number of data items displayed on each page :param pager_count: The maximum number of displayed page numbers usage: queryset = model.objects.all() page_obj = Pagination(current_page,all_count) page_data = queryset[page_obj.start:page_obj.end] To obtain data, use page_data instead of the original queryset. Get the front-end paging style using page_obj.page_html """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page < 1: current_page = 1 self.current_page = current_page self.all_count = all_count self.per_page_num = per_page_num #Total page number all_pager, tmp = divmod(all_count, per_page_num) if tmp: all_pager + = 1 self.all_pager = all_pager self.pager_count = pager_count self.pager_count_half = int((pager_count - 1) / 2) @property def start(self): return (self.current_page - 1) * self.per_page_num @property def end(self): return self.current_page * self.per_page_num def page_html(self): # If the total page number < 11: if self.all_pager <= self.pager_count: pager_start = 1 pager_end = self.all_pager + 1 # Total pages > 11 else: # If the current page <=, at most 11/2 page numbers will be displayed on the page if self.current_page <= self.pager_count_half: pager_start = 1 pager_end = self.pager_count + 1 #The current page is greater than 5 else: # Turn the page number to the end if (self.current_page + self.pager_count_half) > self.all_pager: pager_end = self.all_pager + 1 pager_start = self.all_pager - self.pager_count + 1 else: pager_start = self.current_page - self.pager_count_half pager_end = self.current_page + self.pager_count_half + 1 page_html_list = [] #Add the previous nav and ul tags page_html_list.append(''' <nav aria-label='Page navigation>' <ul class='pagination'> ''') first_page = '<li><a href="?page=%s">Homepage</a></li>' % (1) page_html_list.append(first_page) if self.current_page <= 1: prev_page = '<li class="disabled"><a href="#">Previous page</a></li>' else: prev_page = '<li><a href="?page=%s">Previous page</a></li>' % (self.current_page - 1,) page_html_list.append(prev_page) for i in range(pager_start, pager_end): if i == self.current_page: temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,) else: temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,) page_html_list.append(temp) if self.current_page >= self.all_pager: next_page = '<li class="disabled"><a href="#">Next page</a></li>' else: next_page = '<li><a href="?page=%s">Next page</a></li>' % (self.current_page + 1,) page_html_list.append(next_page) last_page = '<li><a href="?page=%s">Last page</a></li>' % (self.all_pager,) page_html_list.append(last_page) #Add tag at the end page_html_list.append(''' </nav> </ul> ''') return ''.join(page_html_list)
form form verification component
Due to the security of verification, the front end does not need verification, but the back end must verify
Custom component
from django import forms from app01 import models class myzx(forms.Form): username = forms.CharField(min_length=3, max_length=8, label='username', error_messages={ 'min_length': 'Username cannot be less than three characters', 'max_length': 'Username cannot be longer than eight characters', 'required': 'Username cannot be empty', }, widget=forms.widgets.TextInput(attrs={'class': 'form-control'}) ) password = forms.CharField(min_length=3, max_length=8, label='password', error_messages={ 'min_length': 'The password cannot be less than three characters', 'max_length': 'Password cannot be larger than eight characters', 'required': 'Password cannot be empty', }, widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'}) ) confirm_password = forms.CharField(min_length=3, max_length=8, label='Confirm password', error_messages={ 'min_length': 'Confirm password cannot be less than three digits', 'max_length': 'The confirmation password cannot be larger than eight characters', 'required': 'Confirm password cannot be empty', }, widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'}) ) email = forms.EmailField( label='mailbox', error_messages={ 'required': 'The mailbox cannot be empty', 'invalid': 'The email format is incorrect' }, widget=forms.widgets.EmailInput(attrs={"class": 'form-control'}) )
You can write the front-end form yourself or use the one provided by the component
obj is the component object defined by itself
<form method="POST"> <p>{<!-- -->{ obj.username }}</p> <p>{<!-- -->{ obj.confirm_password }}</p> <p>{<!-- -->{ obj.confirm_password }}</p> <p>{<!-- -->{ obj.email }}</p> <input type="submit" value="Submit"> </form>
However, when rendering this way, front-end verification will be added by default. However, adding it to the front-end is unsafe, so it is not used.
<form method="POST"> <p><input type="text" name="username" class="form-control" maxlength="8" minlength="3" required="" id="id_username"></p> <p><input type="password" name="confirm_password" class="form-control" maxlength="8" minlength="3" required="" id="id_confirm_password"></p> <p><input type="password" name="confirm_password" class="form-control" maxlength="8" minlength="3" required="" id="id_confirm_password"></p> <p><input type="email" name="email" class="form-control" required="" id="id_email"></p> <input type="submit" value="Submit"> </form>
To add novalidate to the form, you can cancel the above function.
<form method="POST" novalidate>
Verify uploaded data
#Verify data and obtain verification result object form_obj = myforms.MyRegForm(request.POST) #Determine whether all verifications are successful if form_obj.is_valid(): #Data submitted by users (fields and field values in dictionary form) print(form_obj.cleaned_data) else: #The user submitted incorrect data (the error information is the error field and error description information with front-end style) # is a dictionary, the reason why str is rewritten when printing information above print(form_obj.errors)
Semi-completed version of small case
Front end
obj.errors.username.0, you can get the complete error description without front-end tags.
<form method="POST" novalidate>{{ obj.username.label }}{{ obj.username }}{{ obj.errors.username.0 }}
{{ obj.password.label }}{{ obj.password }}{{ obj.errors.password.0 }}
{{ obj.confirm_password.label }}{{ obj.confirm_password }}{{ obj.errors.confirm_password.0 }}
{{ obj.email.label }}{{ obj.email }}{{ obj.errors.email.0 }}
Backend
Data submission can be implemented simply through this method. The content of the form is still there because obj has recorded the data.
In fact, all objects returned by the backend are obj objects, but the first one has no data, so it is mainly used for rendering the interface.
After the data is uploaded, the generated object contains data, so it will carry error information and be rendered to the front end. The two objs are different.
def text(request): if request.method == 'GET': obj = myforms.myzx() return render(request,'zx.html',locals()) else: obj = myforms.myzx(request.POST) if obj.is_valid(): #Print the data that has been verified successfully. Even if the data is wrong, it can be printed. Only the data that has passed the verification will be printed. print("Verification successful",obj.cleaned_data) return HttpResponse("Data verification successful") else: print("Verification failed",obj.errors) print(type(obj.errors)) return render(request,'zx.html',locals())
forms data addition
When writing forms constraints, we can make the field names the same as those involved in models. In this case, the data dictionary of clean_data fully meets the requirements for submitting data.
#In this case, the data does not need to be taken out one by one, and the data can be submitted at once. if obj.is_valid(): models.books.objects.create(**obj.cleaned_data)
forms data editing
If the editing interface requires the content of metadata, you can use the verification function and return the data to the front desk. Moreover, if the data is taken from the database, there will be no problem. The style of the front end is similar to that of add.
def edit_user(request,nid): if request.method == 'GET': \t\t#retrieve data data = models.UserInfo.objects.filter(pk=nid).first() #Pass to forms because it can automatically generate html obj = UserForm({'username':data.username,'email':data.email}) return render(request,'edit_user.html',locals()) #else is a request to modify data else: obj = UserForm(request.POST) if obj.is_valid(): models.UserInfo.objects.filter(pk=id).update(**obj.cleaned_data) return redirect('/users/') else: return render(request,'edit_user.html')
form field list
https://www.cnblogs.com/xiaoyuanqujing/articles/11753466.html
Among them, weight is an important plug-in for generating front-end code.
Returns a radio button whose parameter is a number
zx = fields.ChoiceField( choices = [(1,'money'),(2,'power')] )
Get metadata dynamically
One
Refreshing the interface will execute these codes, which is equivalent to re-retrieving values from the database.
hobby = forms.IntegerField( label='hobby', widget=widgets.Select() ) def __init__(self,*args,**kwargs): super(myzx,self).__init__(*args,**kwargs) print(models.Blog.objects.values_list('id','site_title')) #Note that this sentence must be written at the end, otherwise the value will be overwritten by super. self.fields['hobby'].widget.choices = models.Blog.objects.values_list('id','site_title')
Two
from django.forms.models import ModelChoiceField hobby2 = ModelChoiceField( label='Hobby 2', # is the displayed data part. If you want to specify the displayed content, you need to override the str method of models. queryset=models.Blog.objects.all(), #Just displays the value, which is used for uploading to_field_name='id' )
from front-end html to generate abbreviation-advanced
But it is not recommended, customization is weak
{<!-- -->{obj.as_p}} <ul> {<!-- -->{obj.as_ul}} </ul> <table> {<!-- -->{obj.as_table}} </table>
Front-end string to label
from django.utils safestring import mark_safe txt = mark_safe(txt)
Hook function
Note that these functions must be written in the form class
Local hook function
Strengthen verification for some fields
def clean_username(self): username = self.cleaned_data.get('username') if '88' in username: self.add_error('username','The name cannot contain 88') return username
Global hook function
Use global hook functions for multiple field validation
def clean(self): password = self.cleaned_data.get('password') re_password = self.cleaned_data.get('re_password') if not password == re_password: self.add_error('re_password','The passwords are not equal') return self.cleaned_data
Regular and other form data submission
# # phone = forms.CharField(label='Mobile phone number',validators=[RegexValidator(r'^[0-9] + $', 'Please enter a number'), RegexValidator(r'^159[0-9] + $', 'The number must start with 159')]) # # # # """The following are the knowledge points. You only need to organize them into your blog. When you need to use them, just copy them directly""" # # gender = forms.ChoiceField( # choices=((1, "Male"), (2, "Female"), (3, "Confidential")), # label="gender", # initial=3, # widget=widgets.RadioSelect() # ) # # # # # hobby = forms.ChoiceField( # choices=((1, "Basketball"), (2, "Football"), (3, "Double Color Ball"),), # label="hobby", # initial=3, # widget=widgets.Select() # ) # # hobby1 = forms.MultipleChoiceField( # choices=((1, "Basketball"), (2, "Football"), (3, "Double Color Ball"),), # label="hobby", # initial=[1, 3], # widget=widgets.SelectMultiple() # ) # # keep = forms.ChoiceField( # label="Whether to remember the password", # initial="checked", # widget=forms.widgets.CheckboxInput() # ) # # hobby2 = forms.MultipleChoiceField( # choices=((1, "Basketball"), (2, "Football"), (3, "Double Color Ball"),), # label="hobby", # initial=[1, 3], # widget=forms.widgets.CheckboxSelectMultiple() # )