django - कस्टम फॉर्म के साथ डीजेन्गो इनलाइन फॉर्म




django-forms (2)

नमस्ते, मेरे पास एक डोमेन मॉडल है, जिसका उपयोग डीजांगो ऐप में किया गया है, जिसे मैं एक एकल प्रपत्र पर पेश करना चाहता हूं। मैंने अपने मॉडल को कस्टम मॉडलफॉर्म के साथ बनाया है (बहुत कुछ परिवर्तन नहीं, कुछ फ़ील्ड आदि को निकाल दिया गया है)। मॉडल की निर्भरता इस प्रकार है:

Complaint
   \
    .--- CarInfo
    .--- Customer

मेरा दृश्य फ़ंक्शन इस तरह दिखता है:

def make(request):
  if request.method == 'POST':
    parameters = copy.copy(request.POST)
    complaint = Complaint()
    carInfo = CarInfo()
    customer = Customer()

    customer_form = CustomerForm(parameters, instance=customer)
    carInfo_form = CarInfoForm(parameters, instance=carInfo)
    parameters['complaint_date'] = get_current_date()
    parameters['customer'] = 1 # dummy value to allow validation success
    parameters['car_info'] = 1 # dummy value to allow validation success
    form = ComplaintForm(parameters, instance=complaint)
    if form.is_valid() and customer_form.is_valid() and carInfo_form.is_valid():
      carInfo_form.save()
      customer_form.save()
      parameters['customer'] = customer.id
      parameters['car_info'] = carInfo.id
      form = ComplaintForm(parameters, instance=complaint)
      form.save()
      return index(request)
  else:
    form = ComplaintForm()
    carInfo_form = CarInfoForm()
    customer_form = CustomerForm()
  return render_to_response('complaints/make_complaint.html', {'complaint_form' : form, 'customer_form' : customer_form, 'carInfo' : carInfo_form})

मुझे इस दृष्टिकोण को बहुत पसंद नहीं है, इसके अलावा यह सभी वातावरणों में काम नहीं करता है -मुझे यह काम नहीं करने का कारण नहीं मिला है। मैं इस कोड को थोड़े फिक्स करने में देख रहा हूं और इनलाइन रूपों (http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets) की तरह कुछ पाया है। यह समाधान ठीक लगता है, लेकिन जब से मेरे रूप कस्टम होते हैं मैं इसका उपयोग कर सकता हूं।

शायद कोई मुझे इस तरह के मामले को ठीक से हल करने के बारे में कुछ सलाह दे सकता है। क्लीनर समाधान बहुत सराहना कर रहे हैं

संपादित मेरे लिए एक मामला है, जहां यह समाधान काम नहीं करता है। विदेशी कुंजी पर डमी मूल्यों को सेट करने के बावजूद, जब मैं कॉल करता हूं_अगला () मुझे गलत संदेश मिल जाता है, तो ये कह रहे हैं कि ये फ़ील्ड सेट नहीं हैं। मैं डीजेंजो 1.2.5 के साथ इस समस्या को देख रहा हूं - यह ऐप चलाने के लिए मैं चाहता हूं कि सर्वर पर ऐसा होता है, हालांकि मेरा लैपटॉप (1.2 जीएसएम भी) इस समस्या को नहीं है।


शायद फ़ॉर्डेसेट फ़ैक्टरी और इनलाइन फॉर्मसेट को आपकी समस्या हल करनी चाहिए ... आप मॉडलों से बनाई गई फार्म फ़ील्ड को संशोधित कर सकते हैं या ओवरराइड कर सकते हैं, उप मॉडल के लिए, आप इनलाइन फ़ॉर्मेट्स का उपयोग कर सकते हैं ...

फ़ॉर्मेट्स और इनलाइन फ़ॉर्मेट्स ...

संभव समाधान:

आपकी प्रपत्र परिभाषा में:

class CarInfoFrm(forms.ModelForm):
    class Meta:
        model = CarInfo
        fields = (....)
carInfoForm = inlineformset_factory(Complaint, CarInfo, form=carInfoFrm,)
CustomerForm = inlineformset_factory(Complaint, Customer, form=carInfoFrm,)

आपके विचार में:

complaint = Complaint()
carInfo = CarInfo()
customer = Customer()

cus_form = CustomerForm(parameters, instance=complaint)
car_form = CarInfoForm(parameters, instance=complaint)
comp_form = ComplaintForm(parameters, instance=complaint)

if cus_form.is_valid() and ...... :
    comp = comp_form.save(commit=False)#do not save it yet
    comp.<attr> = "some_value" #you can edit your data before save...
    comp.save()
    car = car_form(commit=False)
    # do as complaint form... edit and save... 

संपादित करें: इनलाइनफॉर्म्स को सहेजते समय मैं उदाहरण के पैरामीटर को परिभाषित करते समय मेस्टेक बना देता हूं। तो मैं इसे सही ...

जब आप मौजूदा रिकॉर्ड अपडेट करते हैं, तो आपको समस्या नहीं होगी, लेकिन इसे पसंद करना बेहतर है:

if comp_form.is_valid():
    comp = comp_form.save(commit=False)
    comp.<attr> = "some_value"
    comp.save()
if car_form.is_valid():
    # edit if neccessary then save...

if cust_form.is_Valid():
    # edit if neccessary then save...

क्या आसान है, जब आप अपना फॉर्म परिभाषित करते हैं, तो आप एक विदेशी कुंजी के माध्यम से एक माता पिता के रूप को सेट करते हैं

carInfoForm = inlineformset_factory(Complaint, CarInfo, form=carInfoFrm,)

और जब आप इनलाइन फॉर्म का उपयोग करते हैं, तो आप इसे अपने माता पिता के साथ पंजीकृत करें,

car_form = CarInfoForm(parameters, instance=complaint)

इसलिए, car_form एक carInfo उदाहरण को स्वीकार नहीं करते हैं, लेकिन एक शिकायत उदाहरण (यह मेरी पहली जवाब में मेरी गलती थी, इसलिए मैं इसे सही करता हूं)। यदि यह एक नया रिकॉर्ड बनाता है, तो यह स्वतः संबंधित शिकायत दर्ज करने के लिए बाध्य करता है यदि यह एक अपडेट है, तो यह केवल उन फ़ील्ड को अपडेट करता है, जिन्हें आप चाहते हैं।

मेरे लिए आईटीई अपने खुद के लिखने के बजाय ढांचे के मोहेड का इस्तेमाल करना बेहतर है। ऐसा करने से, आप डीजेंगो द्वारा किए गए सभी सत्यापन जांच की गारंटी देंगे।


आप अपनी शिकायत मॉडल की शिकायत दर्ज कर सकते हैं

complaint_date = models.DateField(default=datetime.date.today())

इस तरह से आप छुटकारा पा सकते हैं

parameters['complaint_date'] = get_current_date()

आपके मल्टीफ़ॉर्म दृश्य के लिए आप वांछित व्यवहार के लिए एक अनबाउंड फॉर्म का उपयोग कर सकते हैं।

कार और ग्राहक को शिकायत फ़ॉर्म पर एफके को छोड़कर, फ़ॉर्म को मान्य होना चाहिए। एक ही समय में सभी 3 रूपों के .is_valid () की जांच करें और फिर अपनी शिकायत ऑब्जेक्ट पर निर्भर होने वाले 2 फ़ॉर्मों को सहेजें, डेटाबेस (कमर्शियल = फॉल्से) के साथ प्रतिबद्धता के साथ शिकायत ऑब्जेक्ट बनाएं, ग्राहक के आईडी को जोड़ें और उस ऑब्जेक्ट के लिए कार, तो बचाओ।

आपके विचार में

def make(request):
    if request.method == 'POST':
        customer_form = CustomerForm(request.POST)
        carInfo_form = CarInfoForm(request.POST)
        form = ComplaintForm(request.POST)

        if form.is_valid() and customer_form.is_valid() and carInfo_form.is_valid():
            car_instance = carInfo_form.save()
            customer_instance = customer_form.save()

            complaint_instance = form.save(commit=False)
            complaint_instance.car_info = car_instance
            complaint_instance.customer_info = customer_instance          
            complaint_instance.save()

            return index(request)
    else:
        form = ComplaintForm()
        carInfo_form = CarInfoForm()
        customer_form = CustomerForm()

    context = { 'complaint_form' : form,
                'customer_form' : customer_form, 
                'carInfo' : carInfo_form,
              }
    return render_to_response('complaints/make_complaint.html', context, context_instance=RequestContext(request))

संपादित करें:

मॉडल इस तरह दिखते हैं:

class CarInfo(models.Model):
    some_car_info = models.CharField()

class Customer(models.Model):
    some_customer_info = models.CharField()

class Complaint(models.Model):
    car_info = models.ForeignKey(CarInfo)
    customer_info = models.ForeignKey(Customer)
    some_complaint_info = models.CharField()

forms.py इस तरह दिखना चाहिए:

class CarInfoForm(forms.ModelForm):
    class Meta:
        model = CarInfo

class CustomerForm(forms.ModelForm):
    class Meta:
        model = Customer

class ComplaintForm(forms.ModelForm):
    class Meta:
        model = Complaint
        exclude = ('car_info', 'customer_info',) # or include = ('some_complaint_info',)

आइए देखें जो मैंने ऊपर लिखा था उस दृश्य के माध्यम से चलते हैं: form in view docs

  • पहला पास पर, कोई अनुरोध नहीं है। विधि इसलिए हम 3 अनबाउंड फॉर्म बनाते हैं।

    else:
        form = ComplaintForm()
        carInfo_form = CarInfoForm()
        customer_form = CustomerForm()
  • इन रूपों को टेम्पलेट और गाया जाता है।

  • जब दृश्य को फिर से अनुरोध के साथ कहा जाता है। विधि == "पोस्ट" सही का मूल्यांकन करते हैं, तो हम हमारे अनुरोध से डेटा का उपयोग करते हुए 3 बाउंड फॉर्म उदाहरण बनाते हैं। POST

    if request.method == 'POST':
        customer_form = CustomerForm(request.POST)
        carInfo_form = CarInfoForm(request.POST)
        form = ComplaintForm(request.POST)
  • इसके बाद हम प्रत्येक प्रपत्र पर .is_valid () विधि को कॉल करते हैं। हमारे उदाहरण में क्योंकि हम 'शिकायत प्रारूप प्रारूप में' ग्राहक_इनफ़ो 'और' कार_इनफ़ो 'विदेशी कुंजी क्षेत्रों को बाहर कर चुके हैं, प्रत्येक फ़ॉर्म केवल यह देखने के लिए जांच कर रहा है कि चार इनपुट फ़ील्ड मान्य हैं

  • यदि सत्यापन सभी पास हो जाते हैं तो हम अपने फॉर्म को मॉडल में सहेज सकते हैं और जहां हमें हमारी शिकायत की आवश्यक एफके के बारे में सावधान रहने की जरूरत है:

        if form.is_valid() and customer_form.is_valid() and carInfo_form.is_valid():
            car_instance = carInfo_form.save()
            customer_instance = customer_form.save()
  • उन 2 रूपों के साथ हम सामान्य रूप से। () को कॉल कर सकते हैं। हालांकि हम car_instance और customer_instance के लिए वापसी मूल्य प्रदान करेंगे। इन में कारइन्फो और कस्टमर मॉडलों के उदाहरण होंगे जिनमें हम सिर्फ फार्म पर .ave () विधि का उपयोग करते हुए बनाया है।

  • इसके बाद, commit=False () विधि में commit=False तर्क का उपयोग करके, हम बाध्य प्रपत्र (request.POST डेटा युक्त) से एक वस्तु बनाने में सक्षम हैं और इसे डेटाबेस में नहीं सहेज सकते।

            complaint_instance = form.save(commit=False)
            complaint_instance.car_info = car_instance
            complaint_instance.customer_info = customer_instance          
            complaint_instance.save()
  • यह स्पष्ट करने के लिए, आप इस तरह एक नई शिकायत वस्तु भी बना सकते हैं:

    complaint_info = form.cleaned_data.get('some_complaint_info')
    complaint_instance = Complaint(car_info=car_instance, customer_info=customer_instance, some_complaint_info=some_complaint_info)
    complaint_instance.save()
  • प्रस्तुत करना







django-forms