SoFunction
Updated on 2024-10-29

Django ModelForm operations and validation methods

I. Content review

Model

- Database operations
- validate
class A(MOdel):
user =
email =
pwd =

Form

- class LoginForm(Form):
email = ()
user =
pwd =

- is_valid -> regularize every field (field built-in regularity) + clean_fields -> clean(__all__) -> _post_clean
- cleand_data
- error

--------> Recommended Form <---------

ModelForm operation and validation

Model + Form ==> ModelForm. combination of model and form, so has the following functionality:

data validation

database operation

The model has fields to manipulate the database, and the form validation also has those fields, although the coupling is reduced, but the code is duplicated. If you utilize the fields in the model, is it that the fields in the form don't need to be written.

1. Model + Form (previous operation)

class UserType():
caption = (max_length=32)

class UserInfo():
username = (max_length=32)
email = ()
user_type = (to='UserType',to_field='id')

from django import forms
from  import fields

class UserInfoForm():
# username = (max_length=32)<-- models
username = (max_length=32)
# email = ()<-- models
email = ()
# user_type = (to='UserType',to_field='id')<-- models
user_type = (
choices=.values_list('id','caption')
)

# The following action is to have the data updated in real time on the web page.
def __init__(self, *args, **kwargs):
super(UserInfoForm,self).__init__(*args, **kwargs)
['user_type'].choices = .values_list('id','caption')

<body>
<form action="/index/" method="POST" novalidate="novalidate">
{% csrf_token %}
{{ obj.as_p }}
<input type="submit" value="Submit">
</form>
</body>

novalidate : HTML5 input types and browser validation

Django will use HTML5 input types like url, email, and number if the form contains URLField, EmailField, and other integer fields similarly. By default, browsers may perform their own validations on these fields, which may be stricter than Django's validations. If you want to disable this behavior, set the novalidate attribute of the form tag or formulate a different field such as TextInput.

2、ModelForm basic operation

class UserInfoModelForm():

class Meta:
model = # Dependencies established with models
fields = "__all__"

def index(request):
if  == "GET":
obj = UserInfoModelForm()
return render(request,"",{'obj':obj})
elif  == "POST":
obj = UserInfoModelForm()
print(obj.is_valid()) # Here's the method, don't forget the brackets #
print(obj.cleaned_data)
print()
return render(request,"",{'obj':obj})

Customized field names

How to define the field defined on http, customize it to write in Chinese? The previous use is to write the label in the Form. model Form definition to use verbose_name

class UserInfo():
username = (max_length=32, verbose_name='User')
email = (verbose_name='Mailbox')
user_type = (to='UserType',to_field='id', verbose_name='Type')

If not defined in the model, implemented in the modelForm, using labels

class UserInfoModelForm():

class Meta:
model = 
fields = "__all__"
labels = {
'username':'Username',
'email':'Mailbox',
}

Show specified columns

fields = "__all__" # Show all fields
fields = ['username','email'] # Display the specified column
exclude = ['username'] # Exclude Specified Columns

Why can I do validation in modelForm as well?

Inside the form are is_valid, cleaned_data, errors.

# Form Validation:
UserInfoForm -> Form -> BaseForm( embodyis_validand other methods)

# ModelForm validation:
UserInfoModelForm -> ModelForm -> BaseModelForm -> BaseForm

3、ModelForm component

ModelForm

a. class Meta:

model, # Corresponding to Model
fields=None, # field
exclude=None,# Excluded fields
labels=None, # Tips
help_texts=None, # Helpful Hints
widgets=None,# Custom Plug-ins
error_messages=None, # Customized error messages (overall error messages from import NON_FIELD_ERRORS)
field_classes=None # Custom field classes (can also customize fields)
localized_fields=('birth_date',) # localization,as if:Display of data according to different time zones

As:

databases

2016-12-27 04:10:57

Configuration in Setting

TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True

Then show:

2016-12-27 12:10:57

b. Validation of the implementation process

is_valid -> full_clean -> hook -> overall error

c. Dictionary field validation

def clean_field name(self):
# Can throw an exception
# from  import ValidationError
return "New value"

d. For validation

model_form_obj = XXOOModelForm()
model_form_obj.is_valid()
model_form_obj.errors.as_json()
model_form_obj.clean()
model_form_obj.cleaned_data

e. For the creation of

model_form_obj = XXOOModelForm()
#### Page displayed and submitted #####
# Save many-to-many by default
obj = (commit=True)
# do nothing, internally define save_m2m (for saving many-to-many)
obj = (commit=False)
() # Save sheet information
obj.save_m2m() # Save associated many-to-many information

f. For updating and initialization

obj = (id=1)
model_form_obj = XXOOModelForm(,instance=obj)
...

PS: Simple initialization

model_form_obj = XXOOModelForm(initial={...})

Note: Import module names (fields, widgets) and field names are duplicated, so import with individual names.

from django import forms
from  import fields as Ffields
from  import widgets as Fwidgets
class UserInfoModelForm():

is_rmb = (widget=())

class Meta:
model = 
fields = '__all__'
# fields = ['username','email']
# exclude = ['username']
labels = {
'username': 'Username',
'email': 'Mailbox',
}
help_texts = {
'username': '...'
}
widgets = {
'username': (attrs={'class': 'c1'})
}
error_messages = {
'__all__':{# Overall error messages

},
'email': {
'required': 'Mailbox cannot be empty',
'invalid': 'Mailbox format error...',
}
}
field_classes = { # What is the class that defines the field
# 'email': # This can only be filled with classes, with parentheses it's an object.
}

# localized_fields=('ctime',) # which fields to localize

4, ModelForm database operations

4.1 Create data save

If the data validation is ok, then save, which creates the data directly in the database.

if obj.is_valid():
() # Create data

In the following one-to-many and many-to-many relationships:

class UserType():
caption = (max_length=32)

class UserGroup():
name = (max_length=32)

class UserInfo():
username = (max_length=32)
email = ()
user_type = (to='UserType',to_field='id')
u2g = (UserGroup)

In that case, executing the above () will add data to both the UserInfo table and the many-to-many relationship table.

def index(request):
if  == "GET":
obj = UserInfoModelForm()
return render(request,'',{'obj': obj})
elif  == "POST":
obj = UserInfoModelForm()
if obj.is_valid():
() # Equivalent to the following three sentences
# instance = (False)
# ()
# obj.save_m2m()
return render(request,'',{'obj': obj})

4.2 What does save do?

save source code:

def save(self, commit=True):
""""""
if commit:
()# refers to the current model object
self._save_m2m()# Refers to: preservation of m2m objects
else:
self.save_m2m = self._save_m2m
return # Objects of the model class
""""""

So instance = (False) operates nothing.

if obj.is_valid():
instance = (False)
() # Current object table data creation
obj.save_m2m() # Many-to-many table data creation
# These three sentences above are completed with the above  routine。Take it apart and you can customize the operation

4.3 Modification of data

To modify the table data, remember to pass in the instance information as well, otherwise it's new data, not a modification of a row of data.

Edit user information, new url method retains default data

url(r'^user_list/', views.user_list),
url(r'^edit-(\d+)/', views.user_edit),

def user_list(request):
li = ().select_related('user_type') # Only foreign keys are allowed here, not even many-to-many fields #
return render(request,'user_list.html',{'li': li})

def user_edit(request, nid):
# Get user information for the current id object
# Show user already exists data
if  == "GET":
user_obj = (id=nid).first()
mf = UserInfoModelForm(instance=user_obj) # Pass in the default data
return render(request,'user_edit.html',{'mf': mf, 'nid': nid})
elif  == 'POST':
# Information on data modification, to which row of the database is the modification made?
user_obj = (id=nid).first()
mf = UserInfoModelForm(,instance=user_obj) # Designate to whom changes are to be made
if mf.is_valid():
()
else:
print(.as_json())
return render(request,'user_edit.html',{'mf': mf, 'nid': nid})
user_list.html

<body>
<ul>
{% for row in li %}
<li>{{  }} - {{ row.user_type.caption }} - <a href="/edit-{{  }}/" rel="external nofollow" >compiler</a></li>
{% endfor %}
</ul>
</body>

user_edit.html

<body>
<form method="POST" action="/edit-{{ nid }}/">
{% csrf_token %}
{{ mf.as_p }}
<input type="submit" value="Submit" />
</form>
</body>

5. ModelForm hooks, extra fields

Data Validation Hooks

From the above Form and ModelForm, they both inherit from BaseForm, and is_valid is defined in BaseForm, so ModelForm can also use various hooks as well as Form

additional field

Like the checkbox on the web page, do I use submit to the database for one month without login? This just needs session and cookie settings.

class UserInfoModelForm():
is_rmb = (widget=()) # Additional fields

class Meta:
model = 
fields = '__all__'

6. Summary

1. Generate HTML tags: class Meta: ...

2. mf = xxxModelForm(instance=ModelObj) Generate Default Values

3. additional label, is_rmb = (widget=())

4. various validations is_valid() -> various hooks...

5. ()

# or
instance = (False)
()
mf.save_m2m()

ModelForm because the model and form coupling is too close, so generally write small programs with it.

Additional knowledge:Django - rest serialization (custom serializers)

from  import render
from rest_framework.views import APIView
from rest_framework.response import Response
from repository import models
from rest_framework import serializers

class MyField():
  # Return data to to_respresentation
  def get_attribute(self, instance):
    teacher_list = ()
    return teacher_list
  # Formatted data
  def to_representation(self, value):
    ret = []
    for row in value:
      ({'id': ,'name':})
    return ret


class TestSerializer():
  # get_attribute, get the value from the database
  # to_representation, displaying the value in the page
  # level_name = (source='get_level_display') # obj.get_level_display
  # test_char= (source='') # as . across tables
  x1 = ()
  xx = MyField()
  class Meta:
    model = 
    fields = ['name','level_name']

  def get_x1(self,obj):
    pass

directly in the ModelSerializer as get_field

class CouserDetailSerializer():
  course_name = (source='')
  recommend_courses_list = ()
  price_policy_list = ()

  class Meta:
    model = 
    fields = ['id','course_name','recommend_courses_list']

  def get_recommend_courses_list(self,obj):
    ret = []
    course_list = obj.recommend_courses.all()
    for item in course_list:
      ({'id':,'name':})
    return ret

  def get_price_policy_list(self,obj):
    # All pricing strategies for the current course
    # ret = []
    # price_policy_list = .price_policy.all()
    # return ret

    # ret = []
    # price_policy_list = (content_type__app_label='repository',
    #                  content_type__model='course',
    #                  object_id=obj.couser_id)
    # return ret
    return "ssss"

Above this Django ModelForm operation and validation methods is all that I have shared with you, I hope to give you a reference, and I hope you will support me more.