it-swarm.asia

django admin - قم بإضافة حقول نموذج مخصصة ليست جزءًا من النموذج

لدي نموذج مسجل في موقع المسؤول. أحد حقولها عبارة عن تعبير سلسلة طويلة. أرغب في إضافة حقول نموذج مخصصة إلى صفحة الإضافة/التحديث لهذا النموذج في المشرف والتي بناءً على قيم هذه الحقول ، سأقوم بإنشاء تعبير السلسلة الطويلة وحفظه في حقل النموذج ذي الصلة.

كيف أقوم بذلك؟

استكمال: أساسا ما أقوم به هو بناء تعبير رياضي أو سلسلة من الرموز ، يختار المستخدم الرموز (هذه هي الحقول المخصصة التي ليست جزءًا من النموذج) وعندما ينقر فوق حفظ ، أقوم بإنشاء تمثيل تعبير سلسلة من قائمة الرموز وتخزينها في DB. لا أريد أن تكون الرموز جزءًا من النموذج و DB ، ولكن التعبير النهائي هو فقط.

84
michalv82

إما في admin.py أو في forms.py منفصل ، يمكنك إضافة فئة ModelForm ثم تعلن عن الحقول الإضافية الخاصة بك داخل ذلك كما تفعل عادة. لقد قدمت أيضًا مثالًا عن كيفية استخدام هذه القيم في form.save ():

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. قم بتحرير admin.py وقم بتعيين خاصية النموذج للإشارة إلى النموذج الذي قمت بإنشائه أعلاه
  2. قم بتضمين الحقول الجديدة في حقولك أو إعلان الحقول

مثله:

class YourModelAdmin(admin.ModelAdmin):

    form = YourModelForm

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

استكمال: في Django 1.8 ، تحتاج إلى إضافة fields = '__all__' إلى metaclass لـ YourModelForm.

139
Vishnu

من الممكن القيام به في المشرف ، ولكن لا توجد طريقة واضحة جدًا لذلك. وأيضًا ، أود تقديم النصح للحفاظ على معظم منطق الأعمال في النماذج الخاصة بك ، لذلك لن تعتمد على مسؤول Django.

ربما سيكون الأمر أسهل (وربما أفضل) إذا كان لديك حقلان منفصلان في النموذج الخاص بك. ثم أضف طريقة على النموذج الخاص بك تجمعها.

فمثلا:

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)
28
gitaarik

يمكنك دائمًا إنشاء قالب مسؤول جديد ، والقيام بما تحتاجه في admin_view الخاص بك (تجاوز المشرف لإضافة عنوان url إلى admin_view):

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

إذا كنت ترغب فقط في تخزين الحقل المدمج على النموذج وليس الحقلين المنفصلين ، فيمكنك فعل شيء مثل هذا:

لم أفعل شيئًا كهذا ، لذلك لست متأكدًا تمامًا من الطريقة التي ستعمل بها.

3
gitaarik

جانغو 2.1.1 الجواب الرئيسي جعلني في منتصف الطريق للإجابة على سؤالي. لم يساعدني ذلك في حفظ النتيجة في حقل في نموذجي الفعلي. في حالتي ، أردت حقلًا نصيًا يستطيع المستخدم إدخال البيانات إليه ، ثم عندما تتم عملية الحفظ ، تتم معالجة البيانات وتوضع النتيجة في حقل في النموذج وحفظها. بينما أظهرت الإجابة الأصلية كيفية الحصول على القيمة من الحقل الإضافي ، إلا أنها لم تُظهر كيفية حفظها مرة أخرى إلى النموذج على الأقل في Django 2.1.1

يأخذ هذا القيمة من حقل مخصص غير منضم ويعالجها ويحفظها في حقل الوصف الحقيقي الخاص بي:

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__"
2
MangoLassi