ডাটাবেস থেকে জ্যাঞ্জো অবজেক্টটি পুনরায় লোড করুন


160

ডাটাবেস থেকে জ্যাঙ্গো অবজেক্টের অবস্থা কি রিফ্রেশ করা সম্ভব? আমার অর্থ আচরণ মোটামুটি সমান:

new_self = self.__class__.objects.get(pk=self.pk)
for each field of the record:
    setattr(self, field, getattr(new_self, field))

আপডেট: ট্র্যাকারে একটি পুনরায় খোলা / ওয়ন্টফিক্স যুদ্ধের সন্ধান পেয়েছে: http://code.djangoproject.com/ticket/901 । তবুও বুঝতে পারছেন না কেন রক্ষণাবেক্ষণকারীরা এটি পছন্দ করেন না।


একটি সাধারণ এসকিউএল প্রসঙ্গে, এটি অর্থবোধ করে না। ডাটাবেস অবজেক্টটি কেবলমাত্র আপনার লেনদেন শেষ হওয়ার পরে পরিবর্তিত হতে পারে এবং এ commmit। একবার এটি হয়ে গেলে, আপনাকে পরবর্তী এসকিউএল লেনদেনের জন্য অপেক্ষা করতে হবে। কেন যে? আপনি পরবর্তী লেনদেনের জন্য কতক্ষণ অপেক্ষা করতে যাচ্ছেন?
— এস। লট

এটি একটি অযথা ফাংশন বলে মনে হচ্ছে; এটি ইতিমধ্যে ডাটাবেস থেকে অবজেক্টটি পুনরায় দেখা সম্ভব।
— স্টিফান

আমি এটিও চাই, তবে এটি এখানে
— ইউরোপীয় রূপটি

2
এটি যথাযথ নয় কারণ জ্যাঙ্গো মডেল অবজেক্টগুলি প্রক্সি। যদি আপনি একই টেবিলের সারিটি দুটি বস্তুতে পেয়ে থাকেন - x1 = X.objects.get (id = 1); x2 = X.objects.get (id = 1), তারা সমান হিসাবে পরীক্ষা করবে তবে তারা পৃথক বস্তু এবং রাষ্ট্র ভাগ হয় নি। আপনি উভয় স্বাধীনভাবে পরিবর্তন করতে পারেন এবং সেগুলি সংরক্ষণ করতে পারেন - শেষটি সংরক্ষিত ডাটাবেজে সারিটির অবস্থান নির্ধারণ করে। সুতরাং সাধারণ অ্যাসাইনমেন্ট - x1 = X.objects.get (আইডি = 1) দিয়ে পুনরায় লোড করা সঠিক। পুনরায় লোড পদ্ধতিটি থাকার ফলে অনেক লোক ভুলভাবে সেই x1.f = 'নতুন মান' অনুমান করে; (x1.f == x2.f) সত্য।
— পল হিপ্প

উত্তর:


259

জ্যাঙ্গো হিসাবে ১.৮ রিফ্রেশিং অবজেক্টগুলি অন্তর্নির্মিত। ডক্সে লিঙ্ক ।

def test_update_result(self):
    obj = MyModel.objects.create(val=1)
    MyModel.objects.filter(pk=obj.pk).update(val=F('val') + 1)
    # At this point obj.val is still 1, but the value in the database
    # was updated to 2. The object's updated value needs to be reloaded
    # from the database.
    obj.refresh_from_db()
    self.assertEqual(obj.val, 2)

@ fcracker79 হ্যাঁ, এটি কেবলমাত্র 1.8 এ বাস্তবায়িত হয়েছিল। জ্যাঙ্গোর পূর্ববর্তী সংস্করণগুলির জন্য আপনি অন্য উত্তরগুলির সাথে সেরা যাচ্ছেন।
— টিম ফ্লেচার

1
নিশ্চিত নন যে ডক্সে উল্লিখিত "সমস্ত অ-স্থগিত ক্ষেত্রগুলি আপডেট হয়েছে"?
— Yunti

1
@ ইউন্টি আপনি ক্ষেত্রগুলি স্থগিত করতে পারেন , বা স্পষ্টভাবে কেবল ক্ষেত্রগুলির একটি উপসেট চাইবেন এবং ফলস্বরূপ অবজেক্টটি কেবল আংশিকভাবে জনবহুল হবে। refresh_from_dbইতিমধ্যে ইতিমধ্যে জনবহুল ক্ষেত্রগুলি আপডেট করবে।
— 301_ মোভেড_ স্থায়ীভাবে

ডক্সে বিশদটি খুঁজে পাওয়া যায়নি, তবে DoesNotExistকল করার সময় অন্তর্নিহিত অবজেক্টটি মুছে ফেলা থাকলে এটি সঠিকভাবে ব্যতিক্রম ছুঁড়ে দেয় refresh_from_db। অবগতির জন্য।
— টিম টিসডাল

28

আমি এইভাবে ডাটাবেস থেকে অবজেক্টটি পুনরায় লোড করা তুলনামূলকভাবে সহজ পেয়েছি :

x = X.objects.get(id=x.id)

19
হ্যাঁ, তবে ... তার পরে আপনাকে এই অবজেক্টের সমস্ত রেফারেন্স আপডেট করতে হবে। খুব সহজ এবং ত্রুটি-প্রবণ নয়।
— গ্রেপ

2
জিলো যখন জ্যাঙ্গোর বাইরের ডিবিতে আমার বস্তুটি আপডেট করে তখন এটি প্রয়োজনীয় হয়ে পড়েছিল, জ্যাঙ্গো দৃশ্যত অবজেক্টটির একটি ক্যাশে রেখেছিল কারণ এটি পরিবর্তন করার কোনও ধারণা ছিল না।
— বব স্প্রিন

3
django.db.models.loading আমদানি get_model থেকে; উদাহরণ = get_model (দৃষ্টান্ত) .objects.get (pk = উদাহরণ.pk)
— এরিক

1
@grep এই ব্যবহারের ক্ষেত্রে পরীক্ষা লিখতে সবে মাত্র 2 ঘন্টা হারিয়েছে: 1: একটি মডেল শুরু করুন; 2: একটি ফর্মের মাধ্যমে মডেলটি আপডেট করুন; 3: পরীক্ষা করুন যে নতুন মান আপডেট হয়েছে .... সুতরাং হ্যাঁ, ত্রুটিযুক্ত প্রবণ।
— vlad-ardelean

3
আমি মনে করি refresh_from_dbএই সমস্ত সমস্যার সমাধান করে।
— ফ্লিম

16

@ গ্রেপের মন্তব্যের প্রসঙ্গে, এটি করা সম্ভব হবে না:

# Put this on your base model (or monkey patch it onto django's Model if that's your thing)
def reload(self):
    new_self = self.__class__.objects.get(pk=self.pk)
    # You may want to clear out the old dict first or perform a selective merge
    self.__dict__.update(new_self.__dict__)

# Use it like this
bar.foo = foo
assert bar.foo.pk is None
foo.save()
foo.reload()
assert bar.foo is foo and bar.foo.pk is not None

সমাধানের জন্য ধন্যবাদ। যদি কেবল এসও একাধিক ভোটের অনুমতি দেয়!
— ব্যবহারকারী590028

11
জ্যাঙ্গো এখন refresh_from_dbপদ্ধতি সরবরাহ করে।
— ফ্লিম

9

@ ফ্লিম যেমন উল্লেখ করেছে, এটি সত্যিই দুর্দান্ত সমাধান:

foo.refresh_from_db()

এটি ডাটাবেস থেকে সমস্ত ডেটা অবজেক্টে পুনরায় লোড করে।

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