विषय पर बढ़ें

Body - अपडेट्स

🌐 एआई और मनुष्यों द्वारा किया गया अनुवाद

यह अनुवाद मनुष्यों के मार्गदर्शन में एआई द्वारा किया गया है। 🤝

इसमें मूल अर्थ को गलत समझने या अप्राकृतिक लगने आदि जैसी गलतियाँ हो सकती हैं। 🤖

आप हमें एआई LLM को बेहतर मार्गदर्शन करने में मदद करके इस अनुवाद को बेहतर बना सकते हैं।

अंग्रेज़ी संस्करण

PUT के साथ बदलकर अपडेट करना

किसी item को अपडेट करने के लिए आप HTTP PUT operation का उपयोग कर सकते हैं।

आप input data को ऐसे data में बदलने के लिए jsonable_encoder का उपयोग कर सकते हैं जिसे JSON के रूप में संग्रहीत किया जा सके (जैसे NoSQL database के साथ)। उदाहरण के लिए, datetime को str में बदलना।

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str | None = None
    description: str | None = None
    price: float | None = None
    tax: float = 10.5
    tags: list[str] = []


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}


@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
    return items[item_id]


@app.put("/items/{item_id}", response_model=Item)
async def update_item(item_id: str, item: Item):
    update_item_encoded = jsonable_encoder(item)
    items[item_id] = update_item_encoded
    return update_item_encoded

PUT का उपयोग ऐसा data प्राप्त करने के लिए किया जाता है जो मौजूदा data को बदल दे।

बदलने के बारे में चेतावनी

इसका मतलब है कि अगर आप item bar को PUT का उपयोग करके ऐसे body के साथ अपडेट करना चाहते हैं जिसमें यह हो:

{
    "name": "Barz",
    "price": 3,
    "description": None,
}

क्योंकि इसमें पहले से संग्रहीत attribute "tax": 20.2 शामिल नहीं है, input model "tax": 10.5 की default value लेगा।

और data उस "नए" tax 10.5 के साथ सहेजा जाएगा।

PATCH के साथ आंशिक अपडेट्स

आप data को आंशिक रूप से अपडेट करने के लिए HTTP PATCH operation का भी उपयोग कर सकते हैं।

इसका मतलब है कि आप केवल वही data भेज सकते हैं जिसे आप अपडेट करना चाहते हैं, बाकी को वैसा ही छोड़ते हुए।

नोट

PATCH, PUT की तुलना में कम सामान्य रूप से उपयोग और जाना जाता है।

और कई teams आंशिक अपडेट्स के लिए भी केवल PUT का उपयोग करती हैं।

आप इन्हें जैसे चाहें वैसे उपयोग करने के लिए स्वतंत्र हैं, FastAPI कोई प्रतिबंध नहीं लगाता।

लेकिन यह गाइड आपको मोटे तौर पर दिखाती है कि इन्हें कैसे उपयोग करने का इरादा है।

Pydantic के exclude_unset parameter का उपयोग करना

अगर आप आंशिक अपडेट्स प्राप्त करना चाहते हैं, तो Pydantic के model के .model_dump() में parameter exclude_unset का उपयोग करना बहुत उपयोगी है।

जैसे item.model_dump(exclude_unset=True)

इससे केवल उस data के साथ एक dict बनेगा जो item model बनाते समय सेट किया गया था, default values को छोड़कर।

फिर आप इसका उपयोग केवल उस data के साथ एक dict बनाने के लिए कर सकते हैं जो सेट किया गया था (request में भेजा गया), default values को छोड़ते हुए:

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str | None = None
    description: str | None = None
    price: float | None = None
    tax: float = 10.5
    tags: list[str] = []


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}


@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
    return items[item_id]


@app.patch("/items/{item_id}")
async def update_item(item_id: str, item: Item) -> Item:
    stored_item_data = items[item_id]
    stored_item_model = Item(**stored_item_data)
    update_data = item.model_dump(exclude_unset=True)
    updated_item = stored_item_model.model_copy(update=update_data)
    items[item_id] = jsonable_encoder(updated_item)
    return updated_item

Pydantic के update parameter का उपयोग करना

अब, आप .model_copy() का उपयोग करके मौजूदा model की एक copy बना सकते हैं, और अपडेट करने के लिए data वाले dict के साथ update parameter पास कर सकते हैं।

जैसे stored_item_model.model_copy(update=update_data):

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str | None = None
    description: str | None = None
    price: float | None = None
    tax: float = 10.5
    tags: list[str] = []


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}


@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
    return items[item_id]


@app.patch("/items/{item_id}")
async def update_item(item_id: str, item: Item) -> Item:
    stored_item_data = items[item_id]
    stored_item_model = Item(**stored_item_data)
    update_data = item.model_dump(exclude_unset=True)
    updated_item = stored_item_model.model_copy(update=update_data)
    items[item_id] = jsonable_encoder(updated_item)
    return updated_item

आंशिक अपडेट्स Recap

संक्षेप में, आंशिक अपडेट्स लागू करने के लिए आप:

  • (वैकल्पिक रूप से) PUT के बजाय PATCH का उपयोग करें।
  • संग्रहीत data प्राप्त करें।
  • उस data को Pydantic model में रखें।
  • input model से default values के बिना एक dict बनाएँ (exclude_unset का उपयोग करके)।
    • इस तरह आप केवल उन values को अपडेट कर सकते हैं जिन्हें वास्तव में user ने सेट किया है, बजाय इसके कि आपके model में पहले से संग्रहीत values को default values से override कर दें।
  • संग्रहीत model की एक copy बनाएँ, और प्राप्त आंशिक अपडेट्स के साथ उसके attributes को अपडेट करें (update parameter का उपयोग करके)।
  • copied model को ऐसी चीज़ में बदलें जिसे आपकी DB में संग्रहीत किया जा सके (उदाहरण के लिए, jsonable_encoder का उपयोग करके)।
    • यह model की .model_dump() method को फिर से उपयोग करने जैसा है, लेकिन यह सुनिश्चित करता है (और बदलता है) कि values ऐसे data types में हों जिन्हें JSON में बदला जा सके, उदाहरण के लिए, datetime को str में।
  • data को अपनी DB में सहेजें।
  • अपडेट किया गया model लौटाएँ।
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str | None = None
    description: str | None = None
    price: float | None = None
    tax: float = 10.5
    tags: list[str] = []


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}


@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
    return items[item_id]


@app.patch("/items/{item_id}")
async def update_item(item_id: str, item: Item) -> Item:
    stored_item_data = items[item_id]
    stored_item_model = Item(**stored_item_data)
    update_data = item.model_dump(exclude_unset=True)
    updated_item = stored_item_model.model_copy(update=update_data)
    items[item_id] = jsonable_encoder(updated_item)
    return updated_item

टिप

आप वास्तव में इसी तकनीक का उपयोग HTTP PUT operation के साथ भी कर सकते हैं।

लेकिन यहाँ का उदाहरण PATCH का उपयोग करता है क्योंकि इसे इन्हीं use cases के लिए बनाया गया था।

नोट

ध्यान दें कि input model अभी भी validate किया जाता है।

इसलिए, अगर आप ऐसे आंशिक अपडेट्स प्राप्त करना चाहते हैं जो सभी attributes को छोड़ सकते हैं, तो आपको ऐसा model चाहिए जिसमें सभी attributes optional के रूप में चिह्नित हों (default values या None के साथ)।

अपडेट्स के लिए सभी optional values वाले models और creation के लिए required values वाले models में अंतर करने के लिए, आप Extra Models में बताए गए विचारों का उपयोग कर सकते हैं।