Django에서 ModelForm 사용

8599 단어 django
ModelForm 소개
ModelForm은 Django에서 Model 기반 맞춤형 폼을 작성하는 방법으로 Model의 복용성을 높일 수 있다.
사용 시 Django는 django.db.models.Field(데이터베이스 연결용)에 따라 django.forms.Field(표 전단 전시, 백엔드 검증용)으로 자동으로 전환됩니다.
ModelForm 양식 정의
서적 관리의 예를 들면, 이 예에서 정의되었다.
  • title 필드, 저장char, 책 제목 저장
  • 최대 허용 길이 20
  • 데이터베이스의 유일한 값은 데이터베이스에 두 개의 같은 제목의 책을 저장할 수 없다는 것을 의미한다
  • author 필드, Author에 저장된 외부 키, 책을 저장하는 저자
  • Model
    class Article(models.Model): 
    title = models.CharField(max_length=20, unique=True)
    author = models.ForeignKey('Author')

    ModelForm
    class ArticleForm(forms.ModelForm): 
    class Meta:
    model = Article

    Form으로 구성하면 이 ModelForm은 약간 이렇게.
    class ArticleForm(forms.Form): 
    title = forms.CharField(max_length=20)
    author = forms.ModelChoiceField(queryset=Author.objects.all())

    ModelForm 양식 사용자 정의
    ModelForm은 사용자 정의 Field, 오류 정보, 렌더링 방법, 모델 선택 반전 필드 등을 제공합니다.
    ModelForm은 어떻게 사용자 정의합니까?Meta(ModelForm 고유)와 사용자 정의 필드(일반Form에서도 사용 가능)는 두 가지 방법이 있다.
    Meta
    ModelForm은 메타를 통해db를.Field에서 forms로 자동 전환Field, 몇 단계 전환
  • validators 불변
  • 위젯 속성 추가, 즉 앞부분의 렌더링 방식
  • 모델이 포함하는 필드를 수정하고fields를 통해 지정한 필드를 가져오거나 exclude를 통해 지정한 필드를 제외합니다
  • 오류 수정
  • Meta를 통해 ModelForm의
    class ArticleForm(forms.ModelForm): 
    class Meta:
    # Model
    model = Article
    # Form Model Field
    fields = ['title']
    # Form Model Field
    exclude = ['author']
    # error_message
    error_messages = {
    'invalid' = 'invalid title'
    }
    # widget, 80 , 20 textarea
    widgets = {
    'name': Textarea(attrs={'cols': 80, 'rows': 20}),
    }

    Meta의 단점은 필드를 수정할 수 없는validators입니다.validators를 수정하려면 Meta 외부에 같은 이름의 Field를 다시 정의해서 덮어써야 합니다
    Form에 Field 추가 정의
    이것은 Form에서 통용되는 Field를 정의하는 방법으로 ModelForm에서 두 가지 작용을 한다
  • 보충 모델에는 없는 Field - 양식
  • 모델 Field 정의 덮어쓰기
  • 아래의 예를 보십시오. Article에는 타이틀 필드가 포함되어 있습니다. ModelForm에서CharField를ChoiceField로 바꾸고validators를 사용자 정의했습니다.
    주의: 타이틀을 덮어쓸 때, 타이틀을 메타에서 exclude에서 제거하는 것은 선택할 수 있습니다. 삭제하든지 말든지, unique=True이라는 데이터베이스 레벨 제한을 검사해야 하는지 여부입니다.여기서 우리는 검사를 해야 한다. 왜냐하면 ModelForm 검사가 통과된 후에 나는 그것을 데이터베이스에 저장해야 하기 때문이다. 만약 여기에 검사가 없다면 같은 제목의 책 데이터베이스에 부딪히면 저장 타임즈가 틀릴 것이다. 우리는 이 검사를 ModelForm 검사에 넣기를 원한다. 검사를 통과한 후에 try... catch...으로 그것을 포착하는 것이 아니라.
    class ArticleForm(forms.ModelForm): 
    title = forms.ChoiceFied(choices=((1, ' '), (2, ' '),), validators=MaxValueValidator(2))
    class Meta:
    model = Article

    언급할 만한 Field 전환
    AutoField
    이 Field는 ModelForm 양식에 나타나지 않습니다.
    모든 editable=False의 Field는 ModelForm에 나타나지 않습니다.
    BooleanField
    폼을 제출할 때 string으로 통일적으로 식별되고 BooleanField은python의 bool으로 판단되기 때문에 임의의 비공값을 전송하면 BooleanField은 모두 True로 처리되고 빈값을 전송하면 forms.Field의 기본 속성이 required=True으로 교정에 실패하기 때문에False를 채울 수 있는 Field가 필요하다면그럼 이 Field의 required=False을 Form에 수동으로 설치해야 합니다.
    ForeignKey
    ForeignKey는 자동으로 ModelChoiceField로 전환되며, 밑에 있는 옵션 메뉴로 렌더링되며, 기본적으로 렌더링된 옵션은 대응하는 Field의 str으로 표시되며, 제출된 값은 대응하는 Field의 id으로 맞춤형으로 설정할 수 있습니다.
    백엔드에서 제출을 받을 때 자동으로 대응하는 모델에서 id로 찾고ValidationError를 던집니다.
    ManyToManyField
    Many ToMany Field는 자동으로 Model Multiple Choice Field로 바뀌어 다중 선택 상자로 렌더링됩니다. 마찬가지로 기본적으로 렌더링된 옵션은 Field에 대응하는 str으로 표시되고 제출된 값은 Field에 대응하는 id입니다.
    예를 들어 그룹이라는 Many ToMany Field가 'finance' 'develop' 이 두 가지 옵션을 선택했는데 그들의 id는 각각 1과 2이다. 그러면 세계에서 제출한 폼Query String은 group=1&group=2이다.
    ModelForm 양식 초기화
    form = ArticleForm(request.POST)
  • 검사할 때 instance 파라미터를 정의하여 ModelForm에 실례를 초기화할 수 있다. 즉, 후속 수정은 모두 이 실례에 작용한다.
  • 은 initial 매개 변수를 정의하여 ModelForm의 초기 값을 줄 수 있습니다. 같은 이름의 Field는 instance의 값
    article = Article.objects.get(pk=1) 
    author = Author.objects.first()
    form = ArticleForm(request.POST, instance=article, initial={‘author’: author})
  • 을 덮어씁니다.
    여기에 도착했을 때form은article 대상에 연결되었고 author Field의 초기 값은 author 대상입니다.
    if form.is_valid(): form.save()
    여기에 데이터가 로드되는 순서는 instance < initial < request 입니다.POST
    ModelForm 양식 검증
    참고: Form은 내부에 정의된 Field, request만 검사합니다.POST의 나머지 keyword는 무시되고 필터링되며 되돌아오는 cleaned 에 나타나지 않습니다데이터 중.
    form = ArticleForm(request.POST)

    양식 검증
    if form.is_valid(): # 데이터베이스 article = form.save() is_valid()은 표를 전면적으로 검사하기 위해 full_clean()을 호출하고 3단계로 나눈다(기본 Form에 정의됨)
  • 은 각 Field에 따라 단일 Field 검사를 한다(예를 들어 title 필드는 최대 허용 길이 20을 초과했는지 검사한다). 그 중에서 Field.clean()이 실행된 후에 갈고리 clean_[field_name]
  • 을 제공한다.
  • Form이 정의한 Field 간의 의존 관계에 따라 전체 표를 검사한 결과 갈고리 방법은 clean()
  • 사용자 정의 검사 통과 후의 폼 처리, 갈고리는 _post_clean()Meta에 정의된 Field에 unique=True이라는 제한이 있다면 ModelForm은 기존 데이터베이스에 있는 데이터에 따라 이 Field의 값이 존재하는지 확인하고 존재하면 IntegrityError을 던진다.실제 작업에서 unique를 강제로 검사하지 않으면 이 필드를 메타에서 제거하고 ModelForm에서 다시 정의할 수 있습니다.


  • ModelForm 객체 저장save()을 호출할 때 commit=False을 추가하여 즉각적인 저장을 피하고 후속적인 수정이나 보충을 통해 완전한 모델 실례를 얻어 데이터베이스에 저장할 수 있다.
    초기화할 때 instance를 전송했다면 save()을 호출할 때 ModelForm에서 정의한 필드 값으로 전송된 실례의 해당 필드를 덮어쓰고 데이터베이스에 기록합니다.save() 역시 Many ToMany Field를 저장해 줍니다. 만약에 save할 때 commit=False을 사용했다면 Many ToMany Field의 저장은 이 항목을 데이터베이스에 저장한 후에 ModelForm의 save_m2m() 방법을 수동으로 호출해야 합니다.
    동일한 양식을 사용하여 새로 만들기|지정된 인스턴스 업데이트
    일반적인 절차는 다음과 같은 몇 단계로 나뉜다
  • 객체가 데이터베이스에 있는지 확인
  • 이 이미 존재한다면 수동으로 이 실례를 획득한 다음에 관련field 내용을 변경하고 마지막으로 update() 방법으로 데이터베이스에
  • 저장해야 한다
  • 이 존재하지 않으면 새 모델 실례를 만들고 완전한 모델로 수정합니다. save() 방법을 사용하여 데이터베이스에 저장합니다.
  • f = AuthorForm(request.POST) 
    if f.is_valid():
    try:
    # Save the new instance.
    new_author = f.save(commit=False)
    new_author.some_field = f.cleaned_data['some_field']
    new_author.save()
    except IntegrityError:
    #
    # update cleaned_data some_field
    # some_field new_author ,
    Author.objects.filter(pk=f.cleaned_data['pk']).update(f.cleaned_data)

    너무 귀찮아요!사실 Django에서 이미 update_or_create 방법이 상술한 모든 기능을 실현했기 때문에 이 try ... except ...이 실례가 존재하는지 아닌지를 판단하는 것을 피할 수 있다. 이 예를 살펴보자.
    # forms.py 
    class AuthorAddForm(forms.ModelForm):
    # pk
    # , None
    pk = forms.IntegerField(required=False)
    class Meta:
    model = Author
    fields = ['name', 'address']
    def _post_clean(self):
    super(forms.ModelForm, self)._post_clean()
    # pk
    if not self.cleaned_data['pk']:
    # Field
    self.cleaned_data['Origin'] = City.objects.get(Province=' ', City=' ')
    # views.py 
    class AuthorsView(LoginRequiredMixin, TemplateView):
    template_name = 'authors.html'
    def post(self, request):
    form = AuthorAddForm(request.POST)
    result = {}
    if not form.is_valid():
    return form.errors
    # pk , None, update_or_create , create
    # pk , , , update , create
    Author, created = Author.objects.update_or_create(pk=form.cleaned_data['pk'], defaults=form.cleaned_data)
    return Author.pk

    그중 update_or_create은defaults가 아닌 모든 필드를 검출하여 상기 예에서 id=form.cleaned_data['id']이 데이터베이스에 존재하는지 여부를 판단하여 update()이든 create()이든 update()이든 create()이든 모두 cleaned 를 사용한다데이터는 데이터 원본으로 데이터베이스에 기록된다.

    좋은 웹페이지 즐겨찾기