اذهب إلى المحتوى

السؤال

نشر

السلام عليكم 
لدي مشروع لطلاب مدرسة استخدمت فلتر django-filter  لتصفية النتائج ولكن هناك مشكلة في تصدير النتائج حيث يقوم بتصدير كل الاسماء  وليس فقط الناتجة من من التصفية 

 

class StudentFilterView(FilterView):
    model = Student
    filterset_class = StudentFilter2
    template_name = 'employee_information/employees_filter.html'


def export_student_csv(request):
    filter = StudentFilter2(request.GET, queryset=Student.objects.all())
    filtered_queryset = filter.qs
    dataset = StudentResource().export(filtered_queryset)

    # Define the column names
    column_names = [
        'رقم التسجيل',
        'الاسم',
        'اسم الأب',
        'تاريخ الميلاد',
        'صفة التعيين',
        'الجنس',
        'تاريخ التعيين'
    ]

    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="employees.csv"'
    response.write(u'\ufeff'.encode('utf8'))  # BOM (optional...Excel needs it to open UTF-8 file properly)

    writer = csv.writer(response, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
    writer.writerow(column_names)

    for row in dataset:
        writer.writerow(row)

    return response

 

Recommended Posts

  • 0
نشر

يبدو أن الخطأ في تصدير البيانات هو عدم استخدام العرض النتيجة المصفاة filtered_queryset في مكانه الصحيح. بدلاً من ذلك ، يتم استخدام queryset=Student.objects.all() الذي يحصل على جميع البيانات غير المصفاة من النموذج.

لحل هذه المشكلة، يجب استخدام filtered_queryset بدلاً من dataset في حلقة البيانات for، لأن dataset هو ببساطة نتيجة العملية export() التي تم إجراؤها على filtered_queryset، ولكنها لا تمثل النتائج المصفاة.

لذلك، يمكن تعديل الدالة export_student_csv() كما يلي:

def export_student_csv(request):
    filter = StudentFilter2(request.GET, queryset=Student.objects.all())
    filtered_queryset = filter.qs
    dataset = StudentResource().export(filtered_queryset)

    # Define the column names
    column_names = [
        'رقم التسجيل',
        'الاسم',
        'اسم الأب',
        'تاريخ الميلاد',
        'صفة التعيين',
        'الجنس',
        'تاريخ التعيين'
    ]

    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="employees.csv"'
    response.write(u'\ufeff'.encode('utf8'))  # BOM (optional...Excel needs it to open UTF-8 file properly)

    writer = csv.writer(response, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
    writer.writerow(column_names)

    for row in filtered_queryset:
        writer.writerow([
            row.registration_number,
            row.name,
            row.father_name,
            row.date_of_birth,
            row.appointment_position,
            row.gender,
            row.date_of_appointment
        ])

    return response

في هذا الشكل، تم استخدام filtered_queryset بدلاً من dataset في حلقة البيانات for و تم إدخال الحقول الخاصة بكل عنصر من النتائج.

  • 0
نشر

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

بمجرد الحصول على filtered_queryset، يمكن استخدامها لتصدير البيانات في حلقة البيانات for بدلاً من dataset الذي يتم إنشاؤه باستخدام StudentResource().export() والذي لا يمثل النتائج المصفاة بشكل صحيح.

بالإضافة إلى ذلك، يمكن استخدام الدالة get_queryset() في فئة العرض (FilterView) لتحديد queryset الأساسي الذي يتم تمريره إلى filter.qs بدلاً من Student.objects.all(). هذا يمكن أن يساعد في تحسين أداء التطبيق عند التعامل مع مجموعة كبيرة من السجلات.

مثال:

from django_filters.views import FilterView
from django_tables2.views import SingleTableView
from django_tables2.export.views import ExportMixin
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django_filters.filters import (
    CharFilter,
    NumberFilter,
)
from .models import Student
from .filters import StudentFilter
from .tables import StudentTable
from .resources import StudentResource

class StudentListView(ExportMixin, SingleTableView):
    model = Student
    table_class = StudentTable
    template_name = "students/student_list.html"
    export_formats = (
        "csv",
        "xlsx",
    )
    filterset_class = StudentFilter

    # تحديد queryset الأساسي
    def get_queryset(self):
        queryset = super().get_queryset()
        # تطبيق التصفية على queryset الأساسي وتعديله
        self.filterset = self.filterset_class(self.request.GET, queryset=queryset)
        self.filtered_queryset = self.filterset.qs

        return self.filtered_queryset

    def get_table_data(self):
        # استخدام filtered_queryset بدلاً من queryset الأساسي
        return self.filtered_queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # تمرير filter و table إلى النموذج في context
        context["filter"] = self.filterset
        context["table"] = self.table
        return context

    def get_export_queryset(self, queryset):
        # استخدام filtered_queryset بدلاً من queryset الأساسي للتصدير
        return self.filtered_queryset

    def get_export_resource_class(self):
        # استخدام filtered_queryset بدلاً من queryset الأساسي للتصدير
        return StudentResource

class StudentFilterView(FilterView):
    model = Student
    filterset_class = StudentFilter
    template_name = "students/student_filter.html"
    # تحديد queryset الأساسي
    def get_queryset(self):
        return Student.objects.all()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = _("Filter Students")
        return context

    def get_success_url(self):
        # إعادة توجيه العرض بعد تقديم النموذج
        return reverse_lazy("student_list") + "?" + self.request.GET.urlencode()

في هذا المثال، تم إنشاء عرض Django يستخدم FilterView و SingleTableView من Django-Tables2 و ExportMixin لتمكين تصدير بيانات جدولية باستخدام django-import-export. تم تحديد النموذج الأساسي والفئة المرشحة وفئة الجدول والمورد لاستخدامها في العرض.

وتم استخدام الدالة get_queryset() لتحديد queryset الأساسي الذي سيتم تمريره إلى filter.qs بدلاً من Student.objects.all(). في هذا المثال، تم تطبيق عامل تصفية يقوم بفلترة الطلاب حسب الاسم الأول الذي يبدأ بحرف "J".

مع استخدام الدالة get_table_data() لاسترداد البيانات التي سيتم عرضها في الجدول. في هذا المثال، تم استخدام filter.qs بدلاً من queryset الأصلي.

ثم استخدام الدالة get_export_resource_kwargs() لتحديد البيانات التي سيتم تصديرها. في هذا المثال، تم استخدام filter.qs بدلاً من queryset الأصلي.

وهناك سؤال متعلق بنفس النقاش يمكنك قرائته أيضًا.

 

بتاريخ 5 دقائق مضت قال Abuabar Aliraqi:

للاسف يا صديقي لم ينفع الحل رغم انه منطقيا صحيح ولكن لا اعرف اين الخل 
هل من طريقة اخرى غير filter-django ؟

من الممكن أن تكون الأسباب التالية هي السبب:

1- عدم تعريف الحقول المراد تصديرها في الـ ModelResource: يجب التأكد من تعريف حقول النموذج التي يجب تصديرها في الـ ModelResource المستخدم في الصفحة. يجب تعريف حقول النموذج في Meta.fields في ModelResource.

2- عدم استخدام ModelResource المناسب: يجب التأكد من استخدام ModelResource المناسب لنموذج البيانات الذي يتم تصديره. يجب استخدام ModelResource المناسب الذي يتم تعريفه في نفس التطبيق الذي تم استخدامه في FilterSetClass.

3- عدم تضمين الحقول المراد تصديرها في الـ export_fields: يجب التأكد من تضمين حقول النموذج التي يجب تصديرها في export_fields في ModelResource.

لمساعدتك في تحديد المشكلة الفعلية، يمكنك محاولة إعادة تشغيل الكود مع تفعيل Debug mode في Django، ومراجعة الأخطاء والتحذيرات الخاصة بالمشكلة في ملفات السجلات (Logs). كما يمكنك تحديد المشكلة بمزيد من التحقق من الأسباب المذكورة أعلاه.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...