জাঙ্গো: ফর্মগুলি [বন্ধ] ব্যবহার করে এক টেম্পলেটে একাধিক মডেল


114

আমি একটি সমর্থন টিকিট ট্র্যাকিং অ্যাপ তৈরি করছি এবং আমি কয়েকটি পৃষ্ঠা থেকে একটি পৃষ্ঠা থেকে তৈরি করতে চাই have টিকিটগুলি একটি বিদেশীকের মাধ্যমে কোনও গ্রাহকের অন্তর্ভুক্ত। নোটগুলি বিদেশী কেয়ের মাধ্যমেও টিকিটের সাথে সম্পর্কিত। আমি একটি গ্রাহক বা এটি একটি সম্পূর্ণ পৃথক প্রকল্প) বা নতুন গ্রাহক তৈরি করার পরে টিকিট তৈরির এবং অবশেষে নতুন টিকিটে বরাদ্দকৃত একটি নোট তৈরির বিকল্প পেতে চাই।

যেহেতু আমি জ্যাঙ্গোতে মোটামুটি নতুন, আমি প্রতিবার নতুন বৈশিষ্ট্যগুলি চেষ্টা করে পুনরায় কাজ করার প্রবণতা রাখি। আমি মডেলফর্মের সাথে খেলেছি তবে আমি কিছু ক্ষেত্রগুলি লুকিয়ে রাখতে এবং কিছু জটিল বৈধতা পেতে চাই। দেখে মনে হচ্ছে যে নিয়ন্ত্রণের স্তরের জন্য আমি যাচ্ছি তা ফর্মसेट বা হাতের সাহায্যে সমস্ত কিছু করা দরকার, একটি ক্লান্তিকর, হ্যান্ড-কোডেড টেম্পলেট পৃষ্ঠা দিয়ে সম্পূর্ণ, যা আমি এড়াতে চাইছি।

আমি অনুপস্থিত কিছু সুন্দর বৈশিষ্ট্য আছে? ফর্মসেটগুলি ব্যবহারের জন্য কারও কি ভাল রেফারেন্স বা উদাহরণ রয়েছে? আমি তাদের জন্য এপিআই ডক্সে পুরো সপ্তাহান্তে কাটিয়েছি এবং আমি এখনও নিখুঁত। আমি যদি সবকিছু ভেঙে ফেলে এবং হ্যান্ড-কোড করি তবে এটি কোনও ডিজাইনের সমস্যা?


প্রথমে আপনার গ্রাহক ফর্মটি যাচাই করা উচিত এবং যদি এটি বৈধ হয়, তবে অনুরোধ থেকে একটি অনুলিপি তৈরি করুন O বিদেশী ক্ষেত্রের জন্য গ্রাহক আইডি একটি মান (সম্ভবত আপনার মডেলের গ্রাহক) nd এবং অবশেষে আপনার দ্বিতীয় ফর্মটি (টিকিট) যাচাইয়ের জন্য নতুন_ডেটাকে বিবেচনা করুন
নেগার 37

উত্তর:


87

মডেলফর্মগুলির সাথে এটি বাস্তবায়ন করা খুব কঠিন নয় । সুতরাং আসুন আমরা বলি যে আপনার ফর্ম এ, বি এবং সি রয়েছে আপনার প্রতিটি ফর্ম এবং পৃষ্ঠা মুদ্রণ করে এখন আপনাকে পোস্টটি পরিচালনা করতে হবে।

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
বিটিডব্লিউ, আমি মনে করি না যে ফর্মसेटগুলি আপনার বর্ণিত সমস্যার ভাল সমাধান are আমি সর্বদা এগুলি কোনও মডেলের একাধিক উদাহরণ উপস্থাপন করতে ব্যবহার করি। যেমন আপনার কাছে একজন আবেদনকারী ফর্ম রয়েছে এবং আপনি ৩ টি রেফারেন্স চান আপনার কাছে একটি ফর্মসেট তৈরি করুন যা রেফারেন্স মডেলের 3 টি উদাহরণ রয়েছে।
জেসন ক্রিস্টা

1
নোট করুন, আপনি যেভাবে এটি করেন, সেই সাথে .is_ માન્ય () কলটি সংক্ষিপ্ত প্রচারিত নয়। আপনি যদি এটির শর্ট সার্কিট করতে চান তবে আপনাকে 'এবং' না হওয়া পর্যন্ত .is_ માન્ય () ফাংশনটি কল করতে বিলম্ব করতে হবে।
মিথ্যা রায়ান

66

আমি একদিন আগে ঠিক একই পরিস্থিতিতে ছিলাম এবং আমার 2 সেন্ট এখানে রয়েছে:

1) আমি তর্কসাপেক্ষে এখানে পাওয়া একক আকারে একাধিক মডেল এন্ট্রির সবচেয়ে কম এবং সবচেয়ে সংক্ষিপ্ত বিক্ষোভের: http://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/

সংক্ষেপে: প্রতিটি মডেলের জন্য একটি ফর্ম তৈরি করুন <form>, prefixকীআরগ ব্যবহার করে উভয়কে একক টেমপ্লেটে জমা দিন এবং ভিউ হ্যান্ডেলের বৈধতা পাবেন। যদি নির্ভরতা থাকে তবে কেবল "প্যারেন্ট" মডেলটি নির্ভরতার আগে আপনি সংরক্ষণ করেছেন এবং "শিশু" মডেলটি সংরক্ষণ করার আগে বিদেশী কীর জন্য পিতামাতার আইডি ব্যবহার করবেন তা নিশ্চিত করুন। লিঙ্কটির ডেমো রয়েছে।

2) হতে পারে ফর্মসেটগুলি এটি করার জন্য মারধর করা যেতে পারে, তবে যতক্ষণ না আমি আবিষ্কার করেছি, ফর্মসেটগুলি মূলত একই মডেলের বহুগুণে প্রবেশের জন্য, যা বৈকল্পিকভাবে অন্য মডেল / মডেলগুলির সাথে বিদেশী কী দ্বারা আবদ্ধ হতে পারে। তবে একাধিক মডেলের ডেটা প্রবেশের জন্য কোনও ডিফল্ট বিকল্প নেই বলে মনে হয় এবং ফর্মসেটটি এমনটি বলে মনে হয়।


26

আমার খুব সম্প্রতি কিছু সমস্যা হয়েছিল এবং কীভাবে এটি করা যায় তা সবেমাত্র অনুভব করেছি। ধরে নিলাম আপনার তিনটি ক্লাস রয়েছে, প্রাইমারী, বি, সি এবং বি, সি এর প্রাথমিকের জন্য একটি বিদেশী কী রয়েছে

    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,
      })

এই পদ্ধতির আপনাকে একই যাচাইকরণের যা প্রয়োজন তা করতে একইসাথে একই পৃষ্ঠায় তিনটি অবজেক্ট তৈরি করার অনুমতি দেওয়া উচিত। একই পৃষ্ঠাতে একাধিক বি, সি বস্তুর উত্পন্ন করার জন্য আমি জাভাস্ক্রিপ্ট এবং লুকানো ক্ষেত্রগুলিও ব্যবহার করেছি।


3
এই উদাহরণে, আপনি কীভাবে বি এবং সি মডেলের প্রাথমিক মডেলের দিকে নির্দেশ করতে বিদেশী কীগুলি সেট করছেন?
ব্যবহারকারী

আমার কাছে কেবল দুটি মডেল রয়েছে যা আমি একই ফর্মটিতে প্রদর্শন করতে চাই। তবে আমি বাদ (= 'প্রাথমিক') স্টেটমেন্ট পাই না। প্রাথমিক কি? যদি 2 টি মডেল থাকে গ্রাহককনফিগ এবং চুক্তি। চুক্তিতে গ্রাহককনফাইগের বিদেশী কী রয়েছে। যেমন গ্রাহক_কনফিগ = মডেল F ফোরইনকি ('গ্রাহক পার্টনার কনফিগারেশন') 'প্রাথমিক' কী?
পিচব্ল্যাক 408

10

MultiModelForm থেকে django-betterformsকি বর্ণনা করা হয় কি একটি সুবিধাজনক মোড়কের হয় Gnudiff এর উত্তর । এটি নিয়মিত ModelFormএকটি একক শ্রেণিতে আবৃত করে যা স্বচ্ছভাবে (কমপক্ষে বেসিক ব্যবহারের জন্য) একক ফর্ম হিসাবে ব্যবহৃত হয়। আমি নীচে তাদের ডক্স থেকে একটি উদাহরণ অনুলিপি করেছি।

# 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

আপনার উত্তর জুড়ে আসার আগে সবেমাত্র দেখেছি django-betterformsএবং এর মাল্টিমোডেলফর্ম ক্লাস। তাদের সমাধানটি দেখতে দুর্দান্ত দেখাচ্ছে তবে মনে হয় এটি কিছুক্ষণের মধ্যে আপডেট হয়নি। আপনি কি এখনও এই @ জোজকাইএইক্ক ব্যবহার করছেন? কোন সমস্যা?

@ কয়েক বছর হয়ে গেছে এরপরে আমি এটি সুবিধাজনক এবং আশেপাশের সেরা বিকল্পগুলির মধ্যে একটি পেয়েছি। আপনি যদি এটির সাথে খুব অভিনব না হন তবে এটি কিছুটা সময় সাশ্রয় করে। আমি কল্পনা করতে পারি আপনি যখন অপ্রয়োজনীয় ফর্মগুলি কাস্টমাইজ করা এবং করা শুরু করতে চান তখন আপনার নিজের রোল করা আরও সহজ হবে। ভিউগুলিতে সহজেই ফর্ম এবং প্রসঙ্গের মিশ্রণ হ'ল প্রথম বৈশিষ্ট্যটি যা আমি সত্যিই ভাবি যে আমি জাঙ্গোতে মিস করেছি।
jozxyqk

উত্তর জনতার জন্য ধন্যবাদ। আমি কেবল এটি কাঁটাচামচ করা বিবেচনা করছি এবং সম্ভবত কিছু জিনিস আপডেট করতে চাই। আমি এ পর্যন্ত যা দেখেছি তা থেকে এটি ঠিকঠাক কাজ করছে। আপনি ঠিক বলেছেন, এটি একটি বিশাল সময় সাশ্রয়কারী।

5

আমার বর্তমানে একটি কার্যকরী কার্যকারিতা রয়েছে (এটি আমার ইউনিট পরীক্ষায় পাস করে)। আপনি যখন অন্য মডেলগুলি থেকে সীমিত সংখ্যক ক্ষেত্র যুক্ত করতে চান তবে এটি আমার মতে একটি ভাল সমাধান।

আমি কি এখানে কিছু মিস করছি?

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

3

"আমি কয়েকটি ক্ষেত্র আড়াল করতে চাই এবং কিছু জটিল বৈধতা চাই।"

আমি অন্তর্নির্মিত অ্যাডমিন ইন্টারফেস দিয়ে শুরু করি।

  1. পছন্দসই ক্ষেত্রগুলি দেখানোর জন্য মডেলফর্ম তৈরি করুন।

  2. ফর্মের মধ্যে বৈধতা নিয়ম সহ ফর্মটি প্রসারিত করুন। সাধারণত এটি একটি cleanপদ্ধতি।

    এই অংশটি যুক্তিসঙ্গতভাবে ভাল কাজ করে তা নিশ্চিত হন।

এটি হয়ে গেলে আপনি বিল্ট-ইন অ্যাডমিন ইন্টারফেস থেকে সরে যেতে পারেন।

তারপরে আপনি একক ওয়েব পৃষ্ঠায় একাধিক, আংশিকভাবে সম্পর্কিত ফর্মগুলি দিয়ে বোকা বানাতে পারেন। একক পৃষ্ঠায় সমস্ত ফর্ম উপস্থাপন করার জন্য এটি একগুচ্ছ টেমপ্লেট স্টাফ।

তারপরে আপনাকে বিভিন্ন ফর্মের জিনিসগুলি পড়তে ও যাচাই করতে ভিউ ফাংশনটি লিখতে হবে এবং বিভিন্ন অবজেক্ট সেভ () সংরক্ষণ করে।

"আমি যদি সবকিছু ভেঙে ফেলে এবং হ্যান্ড-কোড করি তবে এটি কোনও ডিজাইনের সমস্যা?" না, খুব বেশি সুবিধা না পাওয়ার জন্য এটি অনেক সময়।


আমি জানি না কীভাবে, সুতরাং এটি করবেন না
orokusaki

1
@ অরোকুসাকি: আপনি আর কী চান? এটি একটি সমাধান বর্ণনা করে বলে মনে হচ্ছে। আর কী বলা উচিত? প্রশ্নটি অস্পষ্ট, সুতরাং প্রকৃত কোড সরবরাহ করা কঠিন। অভিযোগ করার পরিবর্তে, উন্নতির জন্য দয়া করে একটি পরামর্শ দিন। আপনি কি পরামর্শ দিচ্ছেন?
এস .লট

1

জাজানো ডকুমেন্টেশন অনুসারে, ইনলাইন ফর্মসেটগুলি এই উদ্দেশ্যে: "ইনলাইন ফর্মসেটগুলি মডেল ফর্মসেটগুলির শীর্ষে একটি ছোট বিমূর্ত স্তর। এগুলি বিদেশী কী দ্বারা সম্পর্কিত বস্তুর সাথে কাজ করার ক্ষেত্রে সহজতর হয়"।

Https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-forsets দেখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.