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


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.