জ্যাঙ্গোতে কীভাবে নির্বাচন করুন (*) গ্রুপ বা অর্ডার বাছাই করবেন?


99

আমি সিস্টেমের মধ্য দিয়ে যাবতীয় ইভেন্টগুলি ট্র্যাক করে রাখতে একটি লেনদেনের মডেল ব্যবহার করছি

class Transaction(models.Model):
    actor = models.ForeignKey(User, related_name="actor")
    acted = models.ForeignKey(User, related_name="acted", null=True, blank=True)
    action_id = models.IntegerField() 
    ......

আমি কীভাবে আমার সিস্টেমে সেরা 5 অভিনেতা পেতে পারি?

বর্গক্ষেত্রে এটি মূলত হবে

SELECT actor, COUNT(*) as total 
FROM Transaction 
GROUP BY actor 
ORDER BY total DESC

উত্তর:


181

ডকুমেন্টেশন অনুযায়ী আপনার ব্যবহার করা উচিত:

from django.db.models import Count
Transaction.objects.all().values('actor').annotate(total=Count('actor')).order_by('total')

মানগুলি (): "দলবদ্ধ করে" কোন কলামগুলি ব্যবহৃত হবে তা নির্দিষ্ট করে

জ্যাঙ্গো ডক্স:

"যখন ফলাফল সেটটিতে ফিরে আসা কলামগুলিকে সীমাবদ্ধ করার জন্য কোনও মান () ধারাটি ব্যবহার করা হয়, তখন টীকাগুলির মূল্যায়ন করার পদ্ধতিটি কিছুটা আলাদা Qu মানগুলিতে () ধারাটিতে উল্লিখিত ক্ষেত্রগুলির অনন্য সংমিশ্রণে "

এনোটেট (): গোষ্ঠীভুক্ত মানগুলির উপর একটি ক্রিয়াকলাপ নির্দিষ্ট করে

জ্যাঙ্গো ডক্স:

সংক্ষিপ্ত মানগুলি উত্পন্ন করার দ্বিতীয় উপায়টি হল ক্যোরিসেটে প্রতিটি বস্তুর জন্য একটি স্বাধীন সারসংক্ষেপ উত্পন্ন করা। উদাহরণস্বরূপ, আপনি যদি বইগুলির একটি তালিকা পুনরুদ্ধার করে থাকেন তবে আপনি প্রতিটি বইতে কতজন লেখক অবদান রেখেছিলেন তা জানতে চাইতে পারেন। প্রতিটি বইয়ের লেখকের সাথে অনেকগুলি সম্পর্ক রয়েছে; আমরা ক্যোরিসেটের প্রতিটি বইয়ের জন্য এই সম্পর্কের সংক্ষিপ্ত বিবরণ দিতে চাই।

প্রতি-অবজেক্টের সারাংশগুলি টীকা () ধারাটি ব্যবহার করে উত্পন্ন করা যেতে পারে। যখন একটি টীকা () ধারাটি নির্দিষ্ট করা থাকে, ক্যোরিসেটের প্রতিটি বস্তু নির্দিষ্ট মানগুলির সাথে টীকা দেওয়া হবে।

ধারা দ্বারা আদেশ স্বয়ং ব্যাখ্যাযোগ্য।

সংক্ষিপ্তসার হিসাবে: আপনি লেখকদের ক্যোয়ারেট তৈরি করে দলবদ্ধ করুন, টীকা যুক্ত করুন (এটি প্রত্যাবর্তিত মানগুলিতে একটি অতিরিক্ত ক্ষেত্র যুক্ত করবে) এবং শেষ পর্যন্ত, আপনি এই মান দিয়ে তাদের অর্ডার করুন

পড়ুন https://docs.djangoproject.com/en/dev/topics/db/aggregation/ আরও জ্ঞানের জন্য

মনে রাখা ভাল: কাউন্টটি ব্যবহার করা হলে, কাউন্টে পাস করা মান সমষ্টিকে প্রভাবিত করে না, কেবলমাত্র চূড়ান্ত মানকে দেওয়া নাম। সমষ্টিগুলির গোষ্ঠীগুলি মানগুলির অনন্য সংমিশ্রণ দ্বারা (উপরে উল্লিখিত হিসাবে) গণনাতে পাস করা মান দ্বারা নয়। নিম্নলিখিত প্রশ্নগুলি একই:

Transaction.objects.all().values('actor').annotate(total=Count('actor')).order_by('total')
Transaction.objects.all().values('actor').annotate(total=Count('id')).order_by('total')

আমার জন্য এটি হিসাবে কাজ করেছে Transaction.objects.all().values('actor').annotate(total=Count('actor')).order_by('total'), django.db.models থেকে গণনা আমদানি করতে ভুলবেন না। আপনাকে ধন্যবাদ
ইভানচো

4
মনে রাখা ভাল: যদি ব্যবহার করা হয় Count(এবং সম্ভবত অন্যান্য সংগঠনকারী), উত্তীর্ণ হওয়া মানটি Countচূড়ান্ত মানকে দেওয়া নাম হিসাবে সমষ্টিকে প্রভাবিত করে না। একত্রিতকারীর গোষ্ঠীগুলি values(উপরে উল্লিখিত হিসাবে) এর অনন্য সংমিশ্রণ দ্বারা পাস করা মান দ্বারা নয় Count
ক্রোনোসাপিয়েন্স

এমনকি মুখোমুখি হওয়ার জন্য পোস্টগ্রিজ অনুসন্ধান ফলাফলের কোয়েরি সেটগুলির জন্য আপনি এটি ব্যবহার করতে পারেন!
ইয়েকটা

4
@ ক্রোনোসাপিয়েন্স এটি প্রভাবিত করে, আজকাল কমপক্ষে (আমি জ্যাঙ্গো ২.১.৪ ব্যবহার করছি)। উদাহরণস্বরূপ, totalপ্রদত্ত নাম এবং বর্গক্ষেত্রে ব্যবহৃত গণনা COUNT('actor')যা এই ক্ষেত্রে গুরুত্বপূর্ণ নয়, তবে উদাহরণস্বরূপ values('x', 'y').annotate(count=Count('x')), আপনি পাবেন COUNT(x), না COUNT(*)বা COUNT(x, y), কেবল এটি চেষ্টা করেছিলেন./manage.py shell
টাইমডিয়াল

35

ঠিক যেমন @ আলভারো জ্যাঙ্গোর প্রত্যক্ষ সমতুল্য জবাবটি দিয়েছেন GROUP BY:

SELECT actor, COUNT(*) AS total 
FROM Transaction 
GROUP BY actor

নিম্নলিখিত values()এবং annotate()পদ্ধতি ব্যবহারের মাধ্যমে হয়:

Transaction.objects.values('actor').annotate(total=Count('actor')).order_by()

তবে আরও একটি বিষয় অবশ্যই উল্লেখ করা উচিত:

যদি মডেলটির ডিফল্ট অর্ডারিং সংজ্ঞায়িত থাকে class Metaতবে .order_by()উপযুক্ত ফলাফলের জন্য ধারাটি বাধ্যতামূলক। অর্ডারিংয়ের উদ্দেশ্যে না থাকলেও আপনি এটিকে এড়াতে পারবেন না।

তদ্ব্যতীত, একটি উচ্চ মানের কোডের জন্য এটি সর্বদা একটি .order_by()ক্লজ পরে রাখার পরামর্শ দেওয়া হয় annotate(), এমনকি যখন সেখানে কিছু নেই class Meta: ordering। এই জাতীয় দৃষ্টিভঙ্গি বিবৃতিটিকে ভবিষ্যত-প্রমাণ করে তুলবে: এটি ভবিষ্যতের পরিবর্তনগুলি নির্বিশেষে ঠিক যেমনটি ঠিক তেমন কাজ করবে class Meta: ordering


আমি আপনাকে একটি উদাহরণ প্রদান করুন। যদি মডেলটি থাকে:

class Transaction(models.Model):
    actor = models.ForeignKey(User, related_name="actor")
    acted = models.ForeignKey(User, related_name="acted", null=True, blank=True)
    action_id = models.IntegerField()

    class Meta:
        ordering = ['id']

তারপরে এ জাতীয় পদ্ধতির কাজ হবে না:

Transaction.objects.values('actor').annotate(total=Count('actor'))

এজন্য যে জ্যাঙ্গো GROUP BYপ্রতিটি ক্ষেত্রে অতিরিক্ত কাজ করেclass Meta: ordering

আপনি যদি ক্যোয়ারী মুদ্রণ করতে হবে:

>>> print Transaction.objects.values('actor').annotate(total=Count('actor')).query
  SELECT "Transaction"."actor_id", COUNT("Transaction"."actor_id") AS "total"
  FROM "Transaction"
  GROUP BY "Transaction"."actor_id", "Transaction"."id"

এটি পরিষ্কার হয়ে যাবে যে সমষ্টিটি ইচ্ছাকৃতভাবে কাজ করবে না এবং তাই .order_by()এই আচরণটি পরিষ্কার করতে এবং যথাযথ সমষ্টিগত ফলাফলগুলি পাওয়ার জন্য এই ধারাটি অবশ্যই ব্যবহার করা উচিত।

দেখুন: অফিসিয়াল জাজানো ডকুমেন্টেশনে ডিফল্ট ক্রম বা অর্ডার_বি () এর সাথে ইন্টারঅ্যাকশন


4
.order_by()আমাকে orderingমেটা থেকে বাঁচিয়েছে ।
বাবকেন বর্ধনিয়ান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.