سؤال

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

class LocationManager(models.Manager):
    def nearby_locations(self, latitude, longitude, radius, max_results=100, use_miles=True):
        if use_miles:
            distance_unit = 3959
        else:
            distance_unit = 6371

        from django.db import connection, transaction
        cursor = connection.cursor()

        sql = """SELECT id, (%f * acos( cos( radians(%f) ) * cos( radians( latitude ) ) *
        cos( radians( longitude ) - radians(%f) ) + sin( radians(%f) ) * sin( radians( latitude ) ) ) )
        AS distance FROM locations_location HAVING distance < %d
        ORDER BY distance LIMIT 0 , %d;""" % (distance_unit, latitude, longitude, latitude, int(radius), max_results)
        cursor.execute(sql)
        ids = [row[0] for row in cursor.fetchall()]

        return self.filter(id__in=ids)

المشكلة هي أنه لا يمكنني معرفة كيفية الحفاظ على القائمة/ QuerySet مرتبة حسب قيمة المسافة. لا أرغب في القيام بذلك كطريقة إضافية () استدعاء لأسباب الأداء (استعلام واحد مقابل استعلام واحد في كل موقع محتمل في قاعدة البيانات الخاصة بي). بعض الأسئلة:

  1. كيف يمكنني فرز قائمتي بالمسافة؟ حتى خلع النوع الأصلي الذي حددته في النموذج الخاص بي واستخدام "order_by ()" ، لا يزال يتم فرزه بواسطة شيء آخر (معرف ، على ما أعتقد).
  2. هل أنا مخطئ في شيء الأداء وسيقوم Django بتحسين الاستعلام ، لذلك يجب أن أستخدم Extra () بدلاً من ذلك؟
  3. هل هذه هي الطريقة الخاطئة تمامًا للقيام بذلك ، ويجب أن أستخدم مكتبة الجيولوجية بدلاً من تدوير هذا الأمر مثل بوتز؟
هل كانت مفيدة؟

المحلول

لأخذ أسئلتك بترتيب عكسي:

إعادة 3) نعم ، يجب عليك بالتأكيد الاستفادة من Postgis و Geodjango إذا كنت تعمل مع البيانات الجغرافية المكانية. انها مجرد سخيفة لا.

إعادة 2) لا أعتقد أنه يمكنك الحصول على Django للقيام بهذا الاستعلام من أجلك باستخدام .extra () (باستثناء القبول هذه التذكرة) ، لكنه مرشح ممتاز لطريقة .RAW () الجديدة في Django 1.2 (انظر أدناه).

إعادة 1) تحصل على قائمة من المعرفات من استعلامك الأول ، ثم باستخدام استعلام "In" للحصول على مجموعة من الكائنات المقابلة لتلك المعرفات. لا يمكن للاستعلام الثاني الوصول إلى المسافة المحسوبة من الاستعلام الأول ؛ إنه مجرد جلب قائمة من المعرفات (ولا يهتم بالترتيب الذي تقدمه في تلك المعرفات ، أيضًا).

الحلول الممكنة (أقل من التخلص من كل هذا واستخدام Geodjango):

  1. الترقية إلى Django 1.2 Beta واستخدم طريقة .RAW () جديدة. يتيح هذا لـ Django تفسير نتائج استعلام SQL الخام بذكاء وتحويله إلى مجموعة من الكائنات النموذجية الفعلية. مما من شأنه أن يقلل من استفساراتك الحالية إلى واحد ، والحفاظ على الطلب الذي تحدده في SQL. هذا هو الخيار الأفضل إذا كنت قادرًا على إجراء الترقية.

  2. لا تهتم ببناء كائنات نموذج Django QuerySet أو Django على الإطلاق ، ما عليك سوى إضافة جميع الحقول التي تحتاجها في SQL Raw ثم استخدم تلك الصفوف مباشرة من المؤشر. قد لا يكون خيارًا إذا كنت بحاجة إلى طرق النموذج وما إلى ذلك لاحقًا.

  3. قم بتنفيذ خطوة ثالثة في كود Python ، حيث تتكرر على QuerySet وإنشاء قائمة Python من كائنات النموذج بنفس الترتيب مثل قائمة IDS التي عادت إليها من الاستعلام الأول. إرجاع تلك القائمة بدلا من QuerySet. لن تعمل إذا كنت بحاجة إلى إجراء مزيد من التصفية أسفل الخط.

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