سؤال

لدي نموذج لأوامر في تطبيق Webshop، مع مفتاح أساسي زيادة تلقائيا ومفتاحا أجنبي لنفسه، حيث يمكن تقسيم الطلبات إلى أوامر متعددة، ولكن يجب الحفاظ على العلاقة بالترتيب الأصلي.

class Order(models.Model):
    ordernumber = models.AutoField(primary_key=True)
    parent_order = models.ForeignKey('self', null=True, blank=True, related_name='child_orders')
    # .. other fields not relevant here

لقد سجلت فئة طلبية لموقع المسؤول. لعرض التفاصيل، لقد أدرجت parent_order في ال fieldsets ينسب. بالطبع، بشكل افتراضي، يسرد هذا كل الطلبات في المربع تحديد، ولكن هذا ليس السلوك المطلوب. بدلا من ذلك، بالنسبة إلى الطلبات التي لا تملك أمرا الأصلي (أي لم يتم تقسيمها من طلب آخر؛ parent_order لا شيء / لا شيء)، لا ينبغي عرض أوامر. بالنسبة للأوامر التي تم تقسيمها، يجب أن يعرض ذلك فقط أمر الوالد الوحيد.

هناك طريقة modeladmin جديدة إلى حد ما formfield_for_foreignkey, ، يبدو ذلك مثاليا لهذا، حيث يمكن تصفية Queryset داخلها. تخيل أننا نبحث في عرض التفاصيل من أجل # 11234، والذي تم تقسيمه من النظام # 11208. الرمز أدناه

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == 'parent_order':
        # kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=11234)
        return db_field.formfield(**kwargs)
    return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

يعمل الصف التعليق عند تشغيله في قذيفة بيثون، وإرجاع QuerySet عنصر واحد يحتوي على طلب رقم 11208 ل # 11234 وجميع الطلبات الأخرى التي قد تم تقسيمها منه.

بالطبع، لا يمكننا بجد رقم الطلب هناك. نحن بحاجة إلى إشارة إلى ordernumber مجال مثيل الطلب الذي ننظر إليه صفحاته. مثله:

kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=?????)

لقد وجدت أي طريقة عمل لتحل محل ؟؟؟؟؟ مع مرجع إلى مثيل الطلب "الحالي"، لقد حفرت عميقا جدا. self في داخل formfield_for_foreignkey يشير إلى مثيل ModelAdmin، وبينما يكون ذلك model السمة، إنها ليست مثيل نموذج الطلب (إنها مرجع مصممة؛ Self.Model () إرجاع مثيل، ولكن برقم ترتيبها لا شيء).

قد يكون أحد الحلول لسحب رقم الطلب من الطلب .Path (/ المسؤول / الطلبات / الطلب / 11234 /)، ولكن هذا قبيح حقا. أتمنى حقا أن هناك طريقة أفضل.

هل كانت مفيدة؟

المحلول

أعتقد أنك قد تحتاج إلى الاقتراب من ذلك بطريقة مختلفة قليلا - عن طريق تعديل Modelform، بدلا من فئة المشرف. شيء من هذا القبيل:

class OrderForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(OrderForm, self).__init__(*args, **kwargs)
        self.fields['parent_order'].queryset = Order.objects.filter(
            child_orders__ordernumber__exact=self.instance.pk)

class OrderAdmin(admin.ModelAdmin):
    form = OrderForm

نصائح أخرى

لقد نموا صفي المضمنة بهذه الطريقة. إنه قبيح قليلا على كيفية حصوله على معرف النموذج الأصل لتصفية البيانات المضمنة، لكنه يعمل. مرشحات تكنولوجيا المعلومات من قبل شركة من النموذج الأصل.

يتم شرح المفهوم الأصلي هنا http://www.stereoplex.com/blog/filtering-dropdown-lists-in-the-django-admin.

class CompanyOccupationInline(admin.TabularInline):

    model = Occupation
    # max_num = 1
    extra = 0
    can_delete = False
    formset = RequiredInlineFormSet

    def formfield_for_dbfield(self, field, **kwargs):

        if field.name == 'unit':
            parent_company = self.get_object(kwargs['request'], Company)
            units = Unit.objects.filter(company=parent_company)
            return forms.ModelChoiceField(queryset=units)
        return super(CompanyOccupationInline, self).formfield_for_dbfield(field, **kwargs)

    def get_object(self, request, model):
        object_id = resolve(request.path).args[0]
        try:
            object_id = int(object_id)
        except ValueError:
            return None
        return model.objects.get(pk=object_id)

عملت الإجابة المذكورة أعلاه من إروين يوليوس بالنسبة لي، إلا أنني وجدت أن اسم "get_object" يتعارض مع وظيفة django حتى اسم الوظيفة "my_get_object".

class CompanyOccupationInline(admin.TabularInline):

    model = Occupation
    # max_num = 1
    extra = 0
    can_delete = False
    formset = RequiredInlineFormSet

    def formfield_for_dbfield(self, field, **kwargs):

        if field.name == 'unit':
            parent_company = self.my_get_object(kwargs['request'], Company)
            units = Unit.objects.filter(company=parent_company)
            return forms.ModelChoiceField(queryset=units)
        return super(CompanyOccupationInline, self).formfield_for_dbfield(field, **kwargs)

    def my_get_object(self, request, model):
        object_id = request.META['PATH_INFO'].strip('/').split('/')[-1]
        try:
            object_id = int(object_id)
        except ValueError:
            return None
        return model.objects.get(pk=object_id)

أخبرتني أن "أجوبة" الآخرين "، لكنني غير مسموح لي ب" الرد "حتى الآن، وقد كنت أبحث عن ذلك لفترة من الوقت لذلك آمل أن يكون ذلك مفيدا للآخرين. أنا أيضا غير مسموح لي بزيارتك بعد أو أنا سوف!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top