programing

장고: 양식을 사용하여 하나의 템플릿에 여러 개의 모델을 사용합니다.

easyjava 2023. 9. 16. 10:06
반응형

장고: 양식을 사용하여 하나의 템플릿에 여러 개의 모델을 사용합니다.

지원 티켓 추적 앱을 만들고 있는데 한 페이지에서 만들고 싶은 모델이 몇 개 있습니다.티켓은 외국인 키를 통해 고객에게 귀속됩니다.메모는 외국인 키를 통한 티켓에도 속합니다.고객을 선택하거나(이것은 완전히 별개의 프로젝트입니다) 새 고객을 생성한 다음 티켓을 생성하고 마지막으로 새 티켓에 할당된 노트를 생성하는 옵션을 원합니다.

저는 장고가 처음이기 때문에 매번 새로운 기능을 시도하면서 반복적으로 작업하는 편입니다.ModelForms를 사용해 본 적이 있지만 필드 일부를 숨기고 복잡한 검증을 수행하고 싶습니다.제가 찾고 있는 제어 수준은 양식 세트를 필요로 하거나 손으로 모든 작업을 수행해야 하는 것 같습니다. 지루하고 손으로 코드화된 템플릿 페이지가 포함되어 있는데, 이를 피하려고 합니다.

제가 놓친 멋진 기능이 있나요?양식 세트를 사용하는 데 좋은 참고 자료나 예시가 있는 사람이 있습니까?나는 그들을 위해 주말 내내 API 문서 작업을 했는데도 여전히 혼란스럽습니다.제가 모든 것을 분해해서 핸드코딩하면 디자인 문제인가요?

이는 모델폼으로 구현하는 것이 그리 어렵지 않습니다.양식 A, B, C가 있다고 가정해 보겠습니다.양식과 페이지를 각각 출력하면 이제 POST를 처리해야 합니다.

if request.POST():
    a_valid = formA.is_valid()
    b_valid = formB.is_valid()
    c_valid = formC.is_valid()
    # we do this since 'and' short circuits and we want to check to whole page for form errors
    if a_valid and b_valid and c_valid:
        a = formA.save()
        b = formB.save(commit=False)
        c = formC.save(commit=False)
        b.foreignkeytoA = a
        b.save()
        c.foreignkeytoB = b
        c.save()

사용자 지정 유효성 검사를 위한 문서가 여기 있습니다.

저도 하루 전에 거의 비슷한 상황에 처했는데, 여기 제 2센트가 있습니다.

1) 저는 여기 http://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/ 에서 단일 형태로 된 여러 모델 엔트리의 가장 짧고 간결한 데모를 발견했습니다.

말해서, 각 양식을 , 둘 다 , 을 에 에 합니다 로 합니다 에 에 에 템플릿으로 템플릿에 제출합니다.<form>, 를 합니다.prefixkeyarg 및 뷰 핸들 검증을 수행합니다.종속성이 있는 경우에는 종속성 이전에 "부모" 모델을 저장하고, "자녀" 모델 저장을 커밋하기 전에 부모 ID를 외국 키로 사용해야 합니다.링크에 데모가 있습니다.

2) 폼셋은 이 작업을 수행하기 위해 사용될 수 있습니다. 하지만 제가 자세히 설명한 바로는 폼셋은 주로 동일한 모델의 여러 개를 입력하기 위한 것이며, 는 옵션적으로 다른 모델/모델에 외래 키로 연결될 수 있습니다.그러나 두 개 이상의 모델 데이터를 입력할 수 있는 기본 옵션은 없는 것으로 보이며, 이는 폼셋의 용도가 아닌 것으로 보입니다.

저는 아주 최근에 문제가 좀 있어서 어떻게 해야 하는지 막 알아냈습니다.프라이머리, B, C, 그리고 B, C가 프라이머리에 대한 외국 키를 가지고 있다고 가정합니다.

    class PrimaryForm(ModelForm):
        class Meta:
            model = Primary

    class BForm(ModelForm):
        class Meta:
            model = B
            exclude = ('primary',)

    class CForm(ModelForm):
         class Meta:
            model = C
            exclude = ('primary',)

    def generateView(request):
        if request.method == 'POST': # If the form has been submitted...
            primary_form = PrimaryForm(request.POST, prefix = "primary")
            b_form = BForm(request.POST, prefix = "b")
            c_form = CForm(request.POST, prefix = "c")
            if primary_form.is_valid() and b_form.is_valid() and c_form.is_valid(): # All validation rules pass
                    print "all validation passed"
                    primary = primary_form.save()
                    b_form.cleaned_data["primary"] = primary
                    b = b_form.save()
                    c_form.cleaned_data["primary"] = primary
                    c = c_form.save()
                    return HttpResponseRedirect("/viewer/%s/" % (primary.name))
            else:
                    print "failed"

        else:
            primary_form = PrimaryForm(prefix = "primary")
            b_form = BForm(prefix = "b")
            c_form = Form(prefix = "c")
     return render_to_response('multi_model.html', {
     'primary_form': primary_form,
     'b_form': b_form,
     'c_form': c_form,
      })

이 방법을 사용하면 필요한 모든 유효성 검사를 수행할 수 있을 뿐만 아니라 동일한 페이지에서 세 개체를 모두 생성할 수 있습니다.저는 javascript와 hidden 필드를 사용하여 같은 페이지에 여러 개의 B,C 객체를 생성할 수 있도록 했습니다.

MultiModel Form from은 Gnudiff의 답변에 설명된 것을 수행할 수 있는 편리한 포장지입니다.레귤러 랩입니다.ModelForms는 투명하게(적어도 기본적인 사용을 위해) 단일 형태로 사용되는 단일 클래스입니다.저는 아래에 있는 그들의 문서에서 예를 복사했습니다.

# forms.py
from django import forms
from django.contrib.auth import get_user_model
from betterforms.multiform import MultiModelForm
from .models import UserProfile

User = get_user_model()

class UserEditForm(forms.ModelForm):
    class Meta:
        fields = ('email',)

class UserProfileForm(forms.ModelForm):
    class Meta:
        fields = ('favorite_color',)

class UserEditMultiForm(MultiModelForm):
    form_classes = {
        'user': UserEditForm,
        'profile': UserProfileForm,
    }

# views.py
from django.views.generic import UpdateView
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import redirect
from django.contrib.auth import get_user_model
from .forms import UserEditMultiForm

User = get_user_model()

class UserSignupView(UpdateView):
    model = User
    form_class = UserEditMultiForm
    success_url = reverse_lazy('home')

    def get_form_kwargs(self):
        kwargs = super(UserSignupView, self).get_form_kwargs()
        kwargs.update(instance={
            'user': self.object,
            'profile': self.object.profile,
        })
        return kwargs

저는 현재 해결책 기능을 가지고 있습니다(유닛 테스트를 통과했습니다).다른 모델에서 제한된 수의 필드만 추가하고 싶을 때 제 의견에 대한 좋은 해결책입니다.

내가 뭘 빠트렸나요?

class UserProfileForm(ModelForm):
    def __init__(self, instance=None, *args, **kwargs):
        # Add these fields from the user object
        _fields = ('first_name', 'last_name', 'email',)
        # Retrieve initial (current) data from the user object
        _initial = model_to_dict(instance.user, _fields) if instance is not None else {}
        # Pass the initial data to the base
        super(UserProfileForm, self).__init__(initial=_initial, instance=instance, *args, **kwargs)
        # Retrieve the fields from the user model and update the fields with it
        self.fields.update(fields_for_model(User, _fields))

    class Meta:
        model = UserProfile
        exclude = ('user',)

    def save(self, *args, **kwargs):
        u = self.instance.user
        u.first_name = self.cleaned_data['first_name']
        u.last_name = self.cleaned_data['last_name']
        u.email = self.cleaned_data['email']
        u.save()
        profile = super(UserProfileForm, self).save(*args,**kwargs)
        return profile

"밭의 일부를 숨기고 복잡한 검증을 하고 싶습니다."

저는 내장된 관리자 인터페이스부터 시작합니다.

  1. 원하는 필드를 표시하도록 Model Form을 작성합니다.

  2. 양식 내의 유효성 검사 규칙으로 양식을 확장합니다.보통 이거는.clean방법.

    이 부품이 제대로 작동하는지 확인합니다.

이렇게 하면 내장된 관리 인터페이스에서 벗어날 수 있습니다.

그러면 부분적으로 관련된 여러 양식을 하나의 웹 페이지에서 가지고 놀 수 있습니다.이것은 모든 양식을 한 페이지에 보여주기 위한 템플릿들입니다.

그런 다음 보기 기능을 작성하여 다양한 폼을 읽고 검증한 후 다양한 오브젝트 저장()을 수행해야 합니다.

"모든 것을 분해해서 핸드코딩하면 디자인 문제가 됩니까?"아니요, 별로 이득이 되지 않는 시간일 뿐입니다.

장고 문서에 따르면 인라인 폼셋은 이 목적을 위한 것입니다. "인라인 폼셋은 모델 폼셋 위에 있는 작은 추상화 계층입니다.이를 통해 외부 키를 통해 관련 개체를 사용하는 경우가 간소화됩니다."

https://docs.djangoproject.com/en/dev/topics/forms/modelforms/ #http-formset 참조

언급URL : https://stackoverflow.com/questions/569468/django-multiple-models-in-one-template-using-forms

반응형