কীভাবে জাজানো ক্যোয়ারীসেটকে একটি তালিকায় রূপান্তর করবেন


121

আমার নিম্নলিখিতগুলি রয়েছে:

answers = Answer.objects.filter(id__in=[answer.id for answer in answer_set.answers.all()])

তাহলে পরে:

for i in range(len(answers)):
    # iterate through all existing QuestionAnswer objects
    for existing_question_answer in existing_question_answers:
        # if an answer is already associated, remove it from the
        # list of answers to save
        if answers[i].id == existing_question_answer.answer.id:
            answers.remove(answers[i])           # doesn't work
            existing_question_answers.remove(existing_question_answer)

আমি একটি ত্রুটি পেয়েছি:

'QuerySet' object has no attribute 'remove'

আমি কোয়েরীসেটকে একটি স্ট্যান্ডার্ড সেট বা তালিকায় রূপান্তরিত করার জন্য সব ধরণের চেষ্টা করেছি। কিছুই কাজ করে না।

কীভাবে আমি কোয়েরি সেট থেকে কোনও আইটেম সরিয়ে ফেলতে পারি যাতে এটি এটি ডাটাবেস থেকে মুছে না এবং কোনও নতুন ক্যুরিসেট ফেরত দেয় না (যেহেতু এটি এমন লুপে কাজ করবে না)?

উত্তর:


42

আপনি এটি করতে পারেন:

import itertools

ids = set(existing_answer.answer.id for existing_answer in existing_question_answers)
answers = itertools.ifilter(lambda x: x.id not in ids, answers)

ক্যোরিসেটগুলি যখন মূল্যায়ন করা হয় তখন পড়ুন এবং নোট করুন যে পুরো ফলাফলটি মেমরিতে লোড করা ভাল নয় (উদাহরণস্বরূপ list())।

রেফারেন্স: itertools.ifilter

মন্তব্য সম্পর্কিত আপডেট করুন:

এটি করার বিভিন্ন উপায় রয়েছে। একটি (যা সম্ভবত স্মৃতি ও সময়ের নিরিখে সেরা নয়) হুবহু হ'ল:

answer_ids = set(answer.id for answer in answers)
existing_question_answers = filter(lambda x: x.answer.id not in answers_id, existing_question_answers)

আমি উপরের আমার কোডের নমুনায় আরও একটি লাইন যুক্ত করেছি, এক্সাইজিং_কিউশন_আনসওয়ার্স থেকে একই এন্ট্রি মোছা। এটির জন্য কীভাবে কোনও আইফিল্টার ব্যবহার করা সম্ভব?
জন

আমি এটিকে সঠিক হিসাবে চিহ্নিত করব কারণ আমি ফিল্টার সম্পর্কে জানতাম না এবং ল্যাম্বডাস সম্পর্কে ভুলে গিয়েছিলাম।
জন

315

কেন শুধু ডাকে list()না Queryset?

answers_list = list(answers)

এটি QuerySet/ চালানো ক্যোয়ারিকেও মূল্যায়ন করবে । তারপরে আপনি সেই তালিকা থেকে সরিয়ে / যুক্ত করতে পারেন।


9
এটির সাথে সাবধানতা অবলম্বন করুন। আপনি এটিকে তালিকায় কাস্ট করার সময় স্বতন্ত্র পতাকাটিকে অবহেলা করা যেতে পারে।
rh0dium

আমি এটি স্বাধীনভাবে করতে পারি, তবে আমি জাঙ্গো আকারে ক্যোরিসেটে এটি করতে পারি। কোন ধারণা কেন?
ইসমাইলসুন্নি

যদি তা হয় তবে অনন্যগুলি পেতে পুনরায় কাস্ট করুন setএবং তারপরে list
র‌্যাডটেক

36

আপনি যা করতে চেষ্টা করছেন তা অনুসরণ করা একটু কঠিন। আপনার প্রথম বিবৃতি দেখে মনে হচ্ছে আপনি একই উত্তর কোরিয়ারসেটের উত্তর কোয়েস্ট্রেট দুটি বার আনছেন। মাধ্যমে প্রথম answer_set.answers.all()এবং তারপর আবার মাধ্যমে .filter(id__in=...)। শেলটিতে ডাবল চেক করুন এবং দেখুন এটি আপনাকে যে উত্তরগুলির সন্ধান করছে তার তালিকা দেয়:

answers = answer_set.answers.all()

একবার আপনি যে পরিষ্কার তাই এটা একটু সহজ আপনি (এবং কোড কাজ অন্যদের) পড়তে দেখব করতে চান তাদের জন্য আছে .exclude () এবং __in ক্ষেত্র লুকআপ

existing_question_answers = QuestionAnswer.objects.filter(...)

new_answers = answers.exclude(question_answer__in=existing_question_answers)

উপরের চেহারাটি আপনার মডেল সংজ্ঞাগুলির সাথে একত্রীকরণ নাও করতে পারে তবে সম্ভবত এটি আপনাকে নিজের কাজ শেষ করার জন্য পর্যাপ্ত পরিমাণে পেতে পারে।

আপনার যদি এখনও আইডি মানগুলির একটি তালিকা পেতে হয় তবে আপনি .values_list () এর সাথে খেলতে চান । আপনার ক্ষেত্রে আপনি সম্ভবত alচ্ছিক ফ্ল্যাট = সত্য যুক্ত করতে চাইবেন।

answers.values_list('id', flat=True)

আপনার উত্তরের জন্য ধন্যবাদ. দুর্ভাগ্যক্রমে আমি আপনার পদ্ধতির ব্যবহার করতে পারি না তা দেখানোর জন্য আমি যথেষ্ট বিশদ সরবরাহ করিনি।
জন

1
বর্ণিত সমস্যার সেরা সমাধান। আমি new_answers = answers.exclude(question_answer__in=existing_question_answers.values_list('id', flat=True))@istruble যোগ করতে চাই
aquaman

সবচেয়ে পরিষ্কার উপায় flat=Trueধন্যবাদ !!!!!!!
চৌ

18

পদক্ষেপ প্যারামিটার সহ স্লাইস অপারেটরের ব্যবহার যা ক্যোরিসেটের মূল্যায়নের কারণ এবং একটি তালিকা তৈরি করে।

list_of_answers = answers[::1]

অথবা শুরুতে আপনি করতে পারতেন:

answers = Answer.objects.filter(id__in=[answer.id for answer in
        answer_set.answers.all()])[::1]

আমি যতদূর জানি, জ্যাঙ্গো ক্যোয়ারেটটি নেতিবাচক সূচকে সমর্থন করে না।
আলেক্সি সিডাশ

ঠিক আছে আলেক্সি। আপনি ঠিক এখানে আছেন। আমি উত্তর আপডেট করেছি।
অঙ্কিত সিং

15

আপনি listকীওয়ার্ডটি ব্যবহার করে সরাসরি রূপান্তর করতে পারেন । উদাহরণ স্বরূপ:

obj=emp.objects.all()
list1=list(obj)

উপরের কোডটি ব্যবহার করে আপনি সরাসরি একটি কোয়েরি সেট ফলাফলকে একটিতে রূপান্তর করতে পারেন list

এখানে listকীওয়ার্ড এবং objক্যোয়ারী সেটের ফলাফল এবং list1সেই পরিবর্তনশীলটিতে পরিবর্তনশীল আমরা রূপান্তরিত ফলাফলটি সংরক্ষণ করছি list


1
তবে আপনি যদি এটি করেন তবে এটি কার্যকর হয় না: list1 = list(emp.objects.all())যা পাল্টা স্বজ্ঞাত বলে মনে হচ্ছে।
জিওএইডসিক

4

কেন শুধু কল .values('reqColumn1','reqColumn2')বা .values_list('reqColumn1','reqColumn2')ক্যুরিসেটে নয়?

answers_list = models.objects.values('reqColumn1','reqColumn2')

result = [{'reqColumn1':value1,'reqColumn2':value2}]

অথবা

answers_list = models.objects.values_list('reqColumn1','reqColumn2')

result = [(value1,value2)]

আপনি এই ক্যোয়ারীসেটে সমস্ত অপারেশন করতে সক্ষম করতে পারেন যা আপনি তালিকার জন্য করছেন।


1
def querySet_to_list(qs):
    """
    this will return python list<dict>
    """
    return [dict(q) for q in qs]

def get_answer_by_something(request):
    ss = Answer.objects.filter(something).values()
    querySet_to_list(ss) # python list return.(json-able)

এই কোডটি জ্যাঙ্গো ক্যোয়ারেটকে অজগর তালিকায় রূপান্তর করে


0

এই চেষ্টা করুন values_list('column_name', flat=True)

answers = Answer.objects.filter(id__in=[answer.id for answer in answer_set.answers.all()]).values_list('column_name', flat=True)

এটি আপনাকে নির্দিষ্ট কলাম মান সহ একটি তালিকা ফিরিয়ে দেবে


0

পরিবর্তে remove()আপনি exclude()ক্যোরিসেট থেকে কোনও বস্তু সরানোর জন্য ফাংশন ব্যবহার করতে পারেন । এটির সিনট্যাক্সের মতোইfilter()

যেমন : -

qs = qs.exclude(id= 1)

উপরের কোডে এটি Q 'থেকে আইডি' 1 'দিয়ে সমস্ত বস্তু সরিয়ে দেয়

অতিরিক্ত তথ্য : -

filter()নির্দিষ্ট বস্তু নির্বাচন করতে exclude()ব্যবহৃত হয় তবে অপসারণ করতে ব্যবহৃত হয়

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