জ্যাঙ্গো অনেক টোমনি ফিল্টার ()


131

আমার একটি মডেল রয়েছে:

class Zone(models.Model):
    name = models.CharField(max_length=128)
    users = models.ManyToManyField(User, related_name='zones', null=True, blank=True)

এবং আমি এর লাইন বরাবর একটি ফিল্টার গঠন করা প্রয়োজন:

u = User.objects.filter(...zones contains a particular zone...)

এটি ব্যবহারকারীর উপর একটি ফিল্টার হতে হবে এবং এটি একটি একক ফিল্টার প্যারামিটার হতে হবে। এর কারণ হ'ল আমি অ্যাডমিন ব্যবহারকারীর চেঞ্জলিস্ট ফিল্টার করার জন্য একটি URL ক্যোয়ারিং স্ট্রিং তৈরি করছি:http://myserver/admin/auth/user/?zones=3

মনে হচ্ছে এটি সহজ হওয়া উচিত তবে আমার মস্তিষ্ক সহযোগিতা করছে না!


8
আমি নিশ্চিত যদি আমি আপনি পেতে নই অধিকার - নয় User.objects.filter(zones__id=<id>)বা User.objects.filter(zones__in=<id(s)>)এই জন্য ভাল?
টমাসজ জিলিয়াস্কি

ঠিক আছে :) বিটিডব্লিউ User.objects.filter(zones__in=<id(s)>)সম্ভবত হওয়া উচিতUser.objects.filter(zones__id__in=<id(s)>)
টমাসজ জিয়েলসিস্কি

21
এই গুগলিং কারও জন্য কেবল এটি চিহ্নিত করতে চেয়েছিলেন, সম্পর্কিত_নাম সেট করা থাকলে এটি কেবলমাত্র কাজ করে। জোন_সেট কাজ করবে না, উদাহরণস্বরূপ। এতে একটি ভাল অর্ধ ঘন্টা নষ্ট করে :-)

উত্তর:


155

টমাসজ যা বলেছিলেন তা কেবল বিশ্রাম দিন।

বহু -বহু-বহু এবং বহু-এক-এক টেস্টে FOO__in=...স্টাইল ফিল্টারগুলির অনেকগুলি উদাহরণ রয়েছে । আপনার নির্দিষ্ট সমস্যার জন্য সিনট্যাক্সটি এখানে:

users_in_1zone = User.objects.filter(zones__id=<id1>)
# same thing but using in
users_in_1zone = User.objects.filter(zones__in=[<id1>])

# filtering on a few zones, by id
users_in_zones = User.objects.filter(zones__in=[<id1>, <id2>, <id3>])
# and by zone object (object gets converted to pk under the covers)
users_in_zones = User.objects.filter(zones__in=[zone1, zone2, zone3])

ডাবল আন্ডারস্কোর (__) সিনট্যাক্স কোয়েস্টেসে কাজ করার সময় পুরো জায়গা জুড়ে ব্যবহৃত হয় ।


ধন্যবাদ @ ম্যাক্সম কিছু উদাহরণের সাথে আরও বর্তমানের লিঙ্কটি আপডেট করা হয়েছে।
istruble

9
ডাবল আন্ডারস্কোর (
এটিকে

আপনি কি দয়া করে বলতে পারেন, আমি যদি زونগুলির সেটগুলিতে থাকা কোনও ব্যবহারকারীদের মধ্যে কেবল একটিই না চাই তবে কী করব? অঞ্চল 1, জোন 3, .. এবং জোন 10
এফআরআর

এর ...__inপরে উদাহরণগুলি দেখুন # filtering on a few zones, by id। যারা একাধিক আইডি / অবজেক্টের জন্য ফিল্টারিং দেখায় (এই ক্ষেত্রে)। জোন 1, জোন 3, এবং জোন 10 আইডি / অবজেক্টের জন্য আপনি কেবল যত্ন করুন। অথবা প্রয়োজনে একটি চতুর্থ যোগ করুন।
istruble

ধন্যবাদ. আমি কেবল একক মানের বিপরীতে ফিল্টার করছিলাম, একক মান সমেত একটি অ্যারের পরিবর্তে।
জিপ্রো

36

নোট করুন যে ব্যবহারকারী যদি কোয়েরিতে ব্যবহৃত একাধিক জোনে থাকতে পারে তবে আপনি সম্ভবত .distinct () যুক্ত করতে চাইতে পারেন। অন্যথায় আপনি একাধিকবার একজন ব্যবহারকারী পান:

users_in_zones = User.objects.filter(zones__in=[zone1, zone2, zone3]).distinct()

1

এটি করার আরেকটি উপায় হ'ল মধ্যবর্তী টেবিলের মধ্য দিয়ে যাওয়া। আমি এটি জ্যাঙ্গো ওআরএম এর মধ্যে প্রকাশ করব:

UserZone = User.zones.through

# for a single zone
users_in_zone = User.objects.filter(
  id__in=UserZone.objects.filter(zone=zone1).values('user'))

# for multiple zones
users_in_zones = User.objects.filter(
  id__in=UserZone.objects.filter(zone__in=[zone1, zone2, zone3]).values('user'))

এটি .values('user')নির্দিষ্ট না হলে এটি দুর্দান্ত হবে তবে জ্যাঙ্গো (সংস্করণ 3.0.7) এর প্রয়োজন মনে হয়েছে to

উপরের কোডটি এসকিউএল উত্সাহিত করবে যা দেখে মনে হচ্ছে:

SELECT * FROM users WHERE id IN (SELECT user_id FROM userzones WHERE zone_id IN (1,2,3))

যা দুর্দান্ত কারণ এটির মধ্যে অন্তর্বর্তী কোনও মিল নেই যা সদৃশ ব্যবহারকারীদের ফিরিয়ে আনতে পারে


ফোন করেই বলা যায়। এটি নিজের মধ্যে কোনও উত্তর নয়। অতিরিক্ত আংশিক উত্তর যুক্ত করার পরিবর্তে আপনার একটি মন্তব্য যুক্ত করা বা QB- এর উত্তর সম্পাদনা করা উচিত।
অ্যান্ডি বাকের

হ্যাঁ - আপনি যদি নিজের উত্তরটি সম্পাদনা করতে চান তবে এটি সম্পূর্ণ নিজের অধিকারে (যদি আপনি কিউবির উত্তর সম্পাদনা করার মতো পর্যাপ্ত কর্মফল না পেয়ে থাকেন?) তবে এটিই সেরা বেজি হবে। আদর্শভাবে স্ট্যাকওভারফ্লোতে "একটি সঠিক উত্তর" রয়েছে। এটি সাধারণত যে খুব ঝরঝরে কাজ করে না তবে এটি লক্ষ্য করার জন্য মূল্যবান।
অ্যান্ডি বাকের 14

@ অ্যান্ডিবেকার রাজি! বিপরীতমুখী QB এর উত্তর সম্ভবত istruble এর উত্তর একটি মন্তব্য করা উচিত, আমি আমার পৃথক উত্তর ওয়ারেন্ট যথেষ্ট যথেষ্ট স্বতন্ত্র বলে মনে করি, কিন্তু আহ ভাল
স্যাম ম্যাসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.