জ্যাঙ্গো অ্যাডমিন - মডেলের অংশ নয় এমন কাস্টম ফর্ম ক্ষেত্রগুলি যুক্ত করুন


106

আমি অ্যাডমিন সাইটে নিবন্ধিত একটি মডেল আছে। এর ক্ষেত্রগুলির একটি হ'ল দীর্ঘ স্ট্রিং এক্সপ্রেশন। আমি অ্যাডমিনে এই মডেলের অ্যাড / আপডেট পৃষ্ঠায় কাস্টম ফর্ম ক্ষেত্রগুলি যুক্ত করতে চাই যে এই ক্ষেত্রগুলির মানগুলির ভিত্তিতে আমি দীর্ঘ স্ট্রিং এক্সপ্রেশনটি তৈরি করব এবং এটি প্রাসঙ্গিক মডেল ক্ষেত্রে সংরক্ষণ করব।

আমি এটা কিভাবে করবো?

আপডেট: মূলত আমি যা করছি তা প্রতীকগুলি থেকে গাণিতিক বা স্ট্রিং এক্সপ্রেশন তৈরি করছে, ব্যবহারকারী প্রতীকগুলি বেছে নেয় (এগুলি এমন কাস্টম ক্ষেত্র যা মডেলের অংশ নয়) এবং যখন সে সংরক্ষণ ক্লিক করে তখন আমি স্ট্রিং এক্সপ্রেশন উপস্থাপনা তৈরি করি প্রতীকগুলির তালিকা এবং এটি ডিবিতে সঞ্চয় করুন। আমি চাই না যে প্রতীকগুলি মডেল এবং ডিবির অংশ, কেবল চূড়ান্ত প্রকাশ।

উত্তর:


156

হয় আপনার অ্যাডমিন.পি বা পৃথক ফর্মগুলিতে আপনি একটি মডেলফর্ম ক্লাস যুক্ত করতে পারেন এবং তারপরে আপনার অতিরিক্ত ক্ষেত্রগুলিকে সাধারণভাবে যেমন ঘোষণা করতে পারেন। আপনি কীভাবে এই মানগুলি ফর্মটিতে ব্যবহার করতে পারেন তার একটি উদাহরণও দিয়েছি। সেভ ():

from django import forms
from yourapp.models import YourModel


class YourModelForm(forms.ModelForm):

    extra_field = forms.CharField()

    def save(self, commit=True):
        extra_field = self.cleaned_data.get('extra_field', None)
        # ...do something with extra_field here...
        return super(YourModelForm, self).save(commit=commit)

    class Meta:
        model = YourModel

অ্যাডমিনে অতিরিক্ত ক্ষেত্রগুলি উপস্থিত হওয়ার জন্য:

  1. আপনার প্রশাসন.পি সম্পাদনা করুন এবং আপনি উপরে তৈরি ফর্মটি উল্লেখ করতে ফর্ম সম্পত্তি সেট করুন
  2. আপনার ক্ষেত্র বা ফিল্ডসেট ঘোষণায় আপনার নতুন ক্ষেত্রগুলি অন্তর্ভুক্ত করুন

এটার মত:

class YourModelAdmin(admin.ModelAdmin):

    form = YourModelForm

    fieldsets = (
        (None, {
            'fields': ('name', 'description', 'extra_field',),
        }),
    )

আপডেট: fields = '__all__'জাজানো ১.৮ এ আপনাকে আপনার মডেলফর্মের মেটাক্লাসে যুক্ত করতে হবে।


2
হ্যাঁ আমি সত্যিই কারণটি জানতে চাই
বিষ্ণু

13
fields = '__all__'আপনার Metaক্লাসে আপনার যুক্ত করা উচিত , অন্যথায় Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is deprecated
জ্যাঙ্গোর

1
@sthzg, কারণ এটি সঠিক নয়। এটি আমাকে ত্রুটি দেয়:YourModelAdmin.list_display[0], 'extra_field' is not a callable or an attribute of 'YourModelAdmin' or found in the model 'YourModel'.
সেরিন

7
যদি কোনও কারণে, আপনি AttributeError: Unable to lookup "extra_field"...একটি labelপান, extra_fieldসংজ্ঞাটিতে একটি যুক্ত করার চেষ্টা করুন । দেখে মনে হয় যে জাঙ্গো তার জন্য এই জাতীয় বৈশিষ্ট্য সংজ্ঞাটির জন্য Modelএবং তার ModelAdminজন্য লেবেলটি "অনুমান" করার চেষ্টা করে ।
alxs

1
এক্সট্রা_ফিল্ড একটি চারফিল্ড () হলে এটি সুন্দরভাবে কাজ করেছে। এটি [লুকোচুরি ফিল্ড যদিও [জ্যাঙ্গো 1.11 এ] থাকলে, একটি ত্রুটি উত্পন্ন হয়েছে Unknown field(s) (extra_field) specified for YourModel. Check fields/fieldsets/exclude attributes of class YourModelAdmin.। এটির জন্য extra_field = forms.CharField(widget=forms.HiddenInput())
কর্মসূচীটি

35

অ্যাডমিনে এটি করা সম্ভব, তবে এটির পক্ষে খুব সহজ কোনও উপায় নেই। এছাড়াও, আমি আপনার মডেলগুলিতে সর্বাধিক ব্যবসায়ের যুক্তি রাখতে পরামর্শ দিতে চাই, যাতে আপনি জ্যাঙ্গো অ্যাডমিনের উপর নির্ভর করেন না।

আপনার মডেলটিতে দুটি পৃথক ক্ষেত্র থাকলে এটি সম্ভবত সহজ (এবং আরও ভাল) হতে পারে। তারপরে আপনার মডেলটিতে এমন একটি পদ্ধতি যুক্ত করুন যা সেগুলি সংযুক্ত করে।

উদাহরণ স্বরূপ:

class MyModel(models.model):

    field1 = models.CharField(max_length=10)
    field2 = models.CharField(max_length=10)

    def combined_fields(self):
        return '{} {}'.format(self.field1, self.field2)

তারপরে প্রশাসকে আপনি combined_fields()কেবলমাত্র পঠনযোগ্য ক্ষেত্র হিসাবে যুক্ত করতে পারেন :

class MyModelAdmin(models.ModelAdmin):

    list_display = ('field1', 'field2', 'combined_fields')
    readonly_fields = ('combined_fields',)

    def combined_fields(self, obj):
        return obj.combined_fields()

আপনি যদি combined_fieldsডাটাবেসে স্টোর সঞ্চয় করতে চান তবে আপনি যখন মডেলটি সংরক্ষণ করেন তখন আপনি এটি সংরক্ষণও করতে পারেন:

def save(self, *args, **kwargs):
    self.field3 = self.combined_fields()
    super(MyModel, self).save(*args, **kwargs)

4
উত্তরের জন্য ধন্যবাদ, তবে এটি আমি খুঁজছি না। আমি চাই না কাস্টম ক্ষেত্রগুলি ডিবিতে সংরক্ষণ করা হবে, কেবল গণনাযুক্ত স্ট্রিং। মূলত আমি যা করছি তা প্রতীকগুলি থেকে গাণিতিক বা স্ট্রিং এক্সপ্রেশন তৈরি করছে, ব্যবহারকারী প্রতীকগুলি বেছে নেয় (এগুলি এমন কাস্টম ক্ষেত্র যা মডেলের অংশ নয়) এবং যখন সে সংরক্ষণ ক্লিক করে তখন আমি তালিকা থেকে স্ট্রিং এক্সপ্রেশন উপস্থাপনা তৈরি করি প্রতীক এবং এটি ডিবিতে সঞ্চয় করুন।
michalv82

@ michalv82 আপনি এটি মডেলের save()পদ্ধতিতে ডাটাবেসেও সংরক্ষণ করতে পারেন , আমার উত্তরের আপডেটগুলি পরীক্ষা করতে পারেন।
গীতারিক

1
আবারও ধন্যবাদ, তবে বিষয়টি হ'ল আমি চূড়ান্ত ক্ষেত্রের সাথে মিলিত ক্ষেত্রগুলি (যেমন প্রতীকগুলি) সংরক্ষণ করতে চাই না, আমি কেবল চূড়ান্ত স্ট্রিংটি সংরক্ষণ করা চাই
michalv82

2 টি ক্ষেত্র সংরক্ষণ করতে সমস্যা হচ্ছে? সংযুক্ত ক্ষেত্রটি কীভাবে উত্পন্ন হয়েছিল তা যদি আপনি জানতে চান তবে এটি কার্যকর হতে পারে।
গীতারিক

6
আবার ধন্যবাদ তবে এটি 2 ক্ষেত্র নয়, সম্ভবত এটি আরও বেশি। আবার, আমি সেগুলি ডিবিতে রাখতে চাই না, সুতরাং এই সমাধানটি আমার পক্ষে কাজ করতে পারে না।
michalv82

5

জ্যাঙ্গো ২.১.১ প্রাথমিক উত্তরটি আমার প্রশ্নের উত্তর দেওয়ার অর্ধেকটা আমাকে পেয়েছে। এটি আমার সত্যিকারের মডেলটির ক্ষেত্রে কোনও ক্ষেত্রের ফলাফল সংরক্ষণ করতে আমাকে সহায়তা করে নি। আমার ক্ষেত্রে আমি এমন একটি পাঠ্যক্ষেত্র চেয়েছিলাম যাতে কোনও ব্যবহারকারী ডেটা প্রবেশ করতে পারে, তারপরে যখন কোনও সংরক্ষণের ঘটনা ঘটে তখন ডেটা প্রক্রিয়া করা হবে এবং ফলাফলটি মডেলটির একটি ক্ষেত্রের মধ্যে রেখে সংরক্ষণ করা হবে। মূল উত্তরটি কীভাবে অতিরিক্ত ক্ষেত্র থেকে মান পাবেন তা দেখানো হয়েছিল, এটি কমপক্ষে জ্যাঙ্গো ২.১.১ এ কীভাবে মডেলটিতে এটি সংরক্ষণ করতে পারে তা দেখায় নি did

এটি একটি আনবাউন্ড কাস্টম ক্ষেত্র, প্রক্রিয়াগুলি থেকে মানটি নেয় এবং এটি আমার আসল বিবরণ ক্ষেত্রে সংরক্ষণ করে:

class WidgetForm(forms.ModelForm):
    extra_field = forms.CharField(required=False)

    def processData(self, input):
        # example of error handling
        if False:
            raise forms.ValidationError('Processing failed!')

        return input + " has been processed"

    def save(self, commit=True):
        extra_field = self.cleaned_data.get('extra_field', None)

        # self.description = "my result" note that this does not work

        # Get the form instance so I can write to its fields
        instance = super(WidgetForm, self).save(commit=commit)

        # this writes the processed data to the description field
        instance.description = self.processData(extra_field)

        if commit:
            instance.save()

        return instance

    class Meta:
        model = Widget
        fields = "__all__"

4

আপনি সর্বদা নতুন অ্যাডমিন টেম্পলেট তৈরি করতে পারেন এবং আপনার প্রশাসক_ভিউতে আপনার যা যা প্রয়োজন তা করতে পারেন (অ্যাডমিনকে ওভাররাইড করুন আপনার অ্যাডমিন_ভিউতে ইউআরএল যুক্ত করুন):

 url(r'^admin/mymodel/mymodel/add/$' , 'admin_views.add_my_special_model')

3

আপনি যদি কেবলমাত্র দুটি পৃথক ক্ষেত্র নয়, কেবলমাত্র মডেলটিতে সম্মিলিত ক্ষেত্রটি সঞ্চয় করতে চান তবে আপনি এরকম কিছু করতে পারেন:

আমি কখনই এরকম কিছু করি নি তাই এটি কীভাবে কার্যকর হবে আমি পুরোপুরি নিশ্চিত নই।

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