Django(9): ModelForm 작업
                                            
 22577 단어  Django
                    
    Model
        -      
        -   
        class A(MOdel):
            user = 
            email = 
            pwd = 
    Form
        - class LoginForm(Form): 
            email = fields.EmailField()
            user = 
            pwd = 
        - is_valid ->          (      )+clean_   -> clean(__all__)  -> _post_clean
        - cleand_data
        - error
    -------->    2. ModelForm 작업 및 검증
Model + Form ==> ModelForm.모델과form의 결합체이기 때문에 다음과 같은 기능이 있습니다.
1. 모델 + Form(이전 작업)
models.py
class UserType(models.Model):
    caption = models.CharField(max_length=32)
class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    email = models.EmailField()
    user_type = models.ForeignKey(to='UserType',to_field='id')forms.py
from django import forms
from django.forms import fields
class UserInfoForm(forms.Form):
    # username = models.CharField(max_length=32)    
    username = fields.CharField(max_length=32)
    # email = models.EmailField()    
    email = fields.EmailField()
    # user_type = models.ForeignKey(to='UserType',to_field='id')    
    user_type = fields.ChoiceField(
        choices=models.UserType.objects.values_list('id','caption')
    )
    #                  。
    def __init__(self, *args, **kwargs):
        super(UserInfoForm,self).__init__(*args, **kwargs)
        self.fields['user_type'].choices = models.UserType.objects.values_list('id','caption')index.html
<body>
    <form action="/index/" method="POST" novalidate="novalidate">
        {% csrf_token %}
        {{ obj.as_p }}
        <input type="submit" value="  ">
    form>
body>novalidate 참고: HTML5 가져오기 유형 및 브라우저 유효성 검사
만약 폼에 URLField, EmailField, 기타 정수 필드가 유사하다면, Django는 URL, 이메일,number 같은 HTML5 입력 형식을 사용할 것입니다.기본적으로 브라우저는 이 필드에 대해 자신만의 검증을 할 수 있으며, 이 검증은 Django의 검증보다 더 엄격할 수 있습니다.이 동작을 사용하지 않으려면 form 탭의novalidate 속성을 설정하거나 TextInput과 같은 다른 필드를 설정하십시오.
2. ModelForm 기본 작업
다음은 모델form을 통해 실현됩니다
forms.py
class UserInfoModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo    #  models       
        fields = "__all__"views.py
def index(request):
    if request.method == "GET":
        obj = UserInfoModelForm()
        return render(request,"index.html",{'obj':obj})
    elif request.method == "POST":
        obj = UserInfoModelForm(request.POST)
        print(obj.is_valid())  #     ,       
        print(obj.cleaned_data)
        print(obj.errors)
        return render(request,"index.html",{'obj':obj})사용자 정의 필드 이름
http에서 정의한 필드를 어떻게 정의합니까? 중국어로 사용자 정의합니까?이전의 용법은 Form에 label을 쓰는 것이다.Model Form 정의는verbosename
models.py
class UserInfo(models.Model):
    username = models.CharField(max_length=32, verbose_name='  ')
    email = models.EmailField(verbose_name='  ')
    user_type = models.ForeignKey(to='UserType',to_field='id', verbose_name='  ')모델에 정의되지 않으면 모델Form에서 실행되며 labels를 사용합니다
class UserInfoModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo
        fields = "__all__"
        labels = {
            'username':'   ',
            'email':'  ',
        }지정된 열을 표시합니다.
fields = "__all__" 위에 표시된 모든 열을 보여줄 수 있습니까?        fields = ['username','email']   #      
        exclude = ['username']          #      왜 모델포엠에서도 검증을 할 수 있습니까?
form에는
is_valid,cleaned_data,errors,# Form  :
    UserInfoForm -> Form -> BaseForm(   is_valid   )
# ModelForm  :
    UserInfoModelForm -> ModelForm -> BaseModelForm -> BaseForm3. ModelForm 구성 요소
ModelForm
    a.  class Meta:
            model,                           #   Model 
            fields=None,                     #   
            exclude=None,                    #     
            labels=None,                     #     
            help_texts=None,                 #       
            widgets=None,                    #      
            error_messages=None,             #        (      from django.core.exceptions import NON_FIELD_ERRORS)
            field_classes=None               #        (        )
            localized_fields=('birth_date',) #    , :          
             :
                    
                    2016-12-27 04:10:57
                setting    
                    TIME_ZONE = 'Asia/Shanghai'
                    USE_TZ = True
                   :
                    2016-12-27 12:10:57
    b.       
        is_valid -> full_clean ->    ->     
    c.       
        def clean_   (self):
            #       
            # from django.core.exceptions import ValidationError
            return "  "
    d.     
        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.     
        model_form_obj = XXOOModelForm(request.POST)
        ####     ,    #####
        #        
            obj = form.save(commit=True)
        #       ,     save_m2m(       )
            obj = form.save(commit=False)
            obj.save()      #       
            obj.save_m2m()  #          
    f.         
        obj = model.tb.objects.get(id=1)
        model_form_obj = XXOOModelForm(request.POST,instance=obj)
        ...
        PS:      
            model_form_obj = XXOOModelForm(initial={...})주의: 모듈 이름 (fields,widgets) 과 필드 이름이 중복되기 때문에 가져올 때 별명을 붙여야 합니다.
from django import forms
from django.forms import fields as Ffields
from django.forms import widgets as Fwidgets
class UserInfoModelForm(forms.ModelForm):
    is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput())
    class Meta:
        model = models.UserInfo
        fields = '__all__'
        # fields =  ['username','email']
        # exclude = ['username']
        labels = {
            'username': '   ',
            'email': '  ',
        }
        help_texts = {
            'username': '...'
        }
        widgets = {
            'username': Fwidgets.Textarea(attrs={'class': 'c1'})
        }
        error_messages = {
            '__all__':{    #       
            },
            'email': {
                'required': '      ',
                'invalid': '      ..',
            }
        }
        field_classes = {  #          
            # 'email': Ffields.URLField  #       ,         。
        }
        # localized_fields=('ctime',)  #         4. ModelForm 데이터베이스 작업
1.1 데이터 저장 만들기
만약 데이터 검증이 ok라면save는 데이터베이스에 데이터를 직접 생성합니다
        if obj.is_valid():
            obj.save()      #     다음 일대다 관계식에서
class UserType(models.Model):
    caption = models.CharField(max_length=32)
class UserGroup(models.Model):
    name = models.CharField(max_length=32)
class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    email = models.EmailField()
    user_type = models.ForeignKey(to='UserType',to_field='id')
    u2g = models.ManyToManyField(UserGroup)이렇게 하면 위의
obj.save()를 실행하면 UserInfo표와 다대다관계표에 데이터가 추가됩니다.views.py
def index(request):
    if request.method == "GET":
        obj = UserInfoModelForm()
        return render(request,'index.html',{'obj': obj})
    elif request.method == "POST":
        obj = UserInfoModelForm(request.POST)
        if obj.is_valid():
            obj.save()  #       
            # instance = obj.save(False)
            # instance.save()
            # obj.save_m2m()
        return render(request,'index.html',{'obj': obj})1.2 save는 어떤 조작을 했습니까?
save 소스:
def save(self, commit=True):
    """"""
    if commit:
        self.instance.save()    #     model  
        self._save_m2m()        #  :  m2m  
    else:
        self.save_m2m = self._save_m2m
    return self.instance    # model     
    """"""그래서
instance = obj.save(False)시에는 아무것도 조작하지 않는다.if obj.is_valid():
    instance = obj.save(False)
    instance.save()     #          
    obj.save_m2m()      #         
    #              obj.save      。           2. 데이터 수정
수정표 데이터는
instance 정보도 전송해야 한다. 그렇지 않으면 새로운 데이터이지 한 줄의 데이터를 수정하는 것이 아니다.사용자 정보 편집, 새 URL 방식으로 기본 데이터 보존
urls.py
    url(r'^user_list/', views.user_list),
    url(r'^edit-(\d+)/', views.user_edit),views.py
def user_list(request):
    li = models.UserInfo.objects.all().select_related('user_type')  #        ,         
    return render(request,'user_list.html',{'li': li})
def user_edit(request, nid):
    #     id       
    #           
    if request.method == "GET":
        user_obj = models.UserInfo.objects.filter(id=nid).first()
        mf = UserInfoModelForm(instance=user_obj)   #          
        return render(request,'user_edit.html',{'mf': mf, 'nid': nid})
    elif request.method == 'POST':
        #        ,           ?
        user_obj = models.UserInfo.objects.filter(id=nid).first()
        mf = UserInfoModelForm(request.POST,instance=user_obj)  #        
        if mf.is_valid():
            mf.save()
        else:
            print(mf.errors.as_json())
        return render(request,'user_edit.html',{'mf': mf, 'nid': nid})user_list.html
<body>
    <ul>
        {% for row in li %}
            <li>{{ row.username }} - {{ row.user_type.caption }} - <a href="/edit-{{ row.id }}/">  a>li>
        {% endfor %}
    ul>
body>user_edit.html
    
5, ModelForm 갈고리, 추가 필드
데이터 검증 갈고리
위의Form과ModelForm에서 그들은 모두BaseForm을 계승하였고
is_valid는BaseForm에서 정의한 것이기 때문에ModelForm도Form과 같이 각종 갈고리를 사용할 수 있다추가 필드
웹 페이지의 checkbox처럼 한 달 안에 로그인을 면제하고 데이터베이스에 제출합니까?이것은 세션과 쿠키만 설정하면 됩니다.
views.py
class UserInfoModelForm(forms.ModelForm):
    is_rmb = fields.CharField(widget=widgets.CheckboxInput())  #     
    class Meta:
        model = models.UserInfo
        fields = '__all__'6. 총결산
    1.   HTML  :class Meta: ...
    2. mf = xxxModelForm(instance=ModelObj)      
    3.      , is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput())
    4.      is_valid() ->     ...
    5.  mf.save()
        #  
        instance = mf.save(False)
        instance.save()
        mf.save_m2m()ModelForm은 모델과form의 결합이 너무 밀접하기 때문에 보통 작은 프로그램을 써서 사용합니다.
전재는 반드시 이 출처를 보존하십시오:http://blog.csdn.net/fgf00/article/details/54917396
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Django 라우팅 계층 URLconf 작용 및 원리 해석URL 구성(URLconf)은 Django가 지원하는 웹 사이트의 디렉토리와 같습니다.그것의 본질은 URL과 이 URL을 호출할 보기 함수 사이의 맵표입니다. 위의 예제에서는 URL의 값을 캡처하고 위치 매개 변수로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.