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

السؤال

نشر

لدي نموذج يمثل المنشورات التي أقدمها على موقعي. وأود أن أعرض بعضًا من العشوائية. لكنني أواجهة مشكلة في الحصول على سجل record عشوائي من قاعدة البيانات. حاول أن أكتب الكود التالي:

number_of_records = Post.objects.count()
random_index = int( random.random() * number_of_records ) + 1
random_post = Post.get(pk = random_index)

لا يبدو أن من الصحيح حساب عدد كل الصفوف للحصول على سجدل عشوائي. هل توجد أي خيارات أخرى كيف تمكنني من القيام بذلك؟

Recommended Posts

  • 1
نشر

يوفر جانغو Django طريقة سهلة للحصول على سجل عشوائي بسطر واحد فقط، كالتالي:

Post.objects.order_by('?').first()

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

random.choice(Post.objects.all())

هذه الطريقة جيدة في قواعد البيانات الصغير (التي تحتوي على أقل من 100,000 من الصفوف في الجدول).

أيضًا يمكنك أن تقوم بعمل نفس الأمر لكن من خلال حساب عدد الكائنات في قاعدة البيانات، على النحو التالي:
 

from random import randint

count = Post.objects.all().count()
random_index = randint(0, count - 1)
random_post = Post.objects.all()[random_index]

 

  • 0
نشر

استخدام 

order_by('?')

سيقوم بايقاف الخادم لمدة ثانتين تقريبا خلال وقت عمله، هناك طريقة أفضل باستخدام المكتبة random المشهورة في بايثون ، الكود التالي يوضح كيفية استخدامها لاداء الغرض المطلوب:

from django.db.models.aggregates import Count
from random import randint

class PaintingManager(models.Manager):
    def random(self):
        count = self.aggregate(count=Count('id'))['count']
        random_index = randint(0, count - 1)
        return self.all()[random_index]

أو بشكل أبسط:

from random import randint

count = Model.objects.count()
random_object = Model.objects.all()[randint(0, count - 1)] #عينة واحدة عشوائية

 

  • 0
نشر

من الممكن أن تكون الإجابات الأخرى أن تكون بطيئة باستخدام order_by ('؟') أو تستخدم أكثر من استعلام SQL. إليك نموذج حل بدون ترتيب واستعلام واحد فقط, بافتراض Postgres:

random_instance_or_none = Model.objects.raw('''
    select * from {0} limit 1
    offset floor(random() * (select count(*) from {0}))
'''.format(Model._meta.db_table)).first()

ربما أن هذا سيؤدي إلى ظهور خطأ في الفهرس إذا كان الجدول فارغ.لذلك اكتب دالة مساعدة للتحقق من ذلك

  • 0
نشر

يمكنك القيام بذلك من خلال تصفية السجلات الأكثر أهمية ثم استخدام random.sample لتحديد أي عدد تريده كالتالي:

import random
from myapp.models import MyModel
qs = MyModel.objects.filter(criteria=True)  #QuerySet الخرج سيكون 
random.sample(qs, 1)  #qs الحصول على عنصر عشوائي واحد من مجموعة الاستعلام السابقة
random.sample(qs, 6)  # الحصول على ستة عناصر
random.sample(qs, 8)  # الحصول على ثمانية 
# وهكذا..

كما يمكنك القيام بإنشاء manager للنموذج الخاص بك للقيام بهذا النوع من الأشياء كالتالي:

from django.db import models
class RandomManager(models.Manager):
    def get_query_set(self):
        return super(RandomManager, self).get_query_set().order_by('?')
class Painting(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)
    objects = models.Manager() # المدير الافتراضي.
    randoms = RandomManager() # مدير عشوائي محدد.

ولاستخدامه:

random_painting = Painting.randoms.all()[0]

 

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...