cari
Rumahpembangunan bahagian belakangTutorial PythonCara Membina Model Data Fleksibel dalam Django dengan JSONField dan Pydantic

How to Build Flexible Data Models in Django with JSONField and Pydantic

Dalam artikel ini, saya akan membimbing anda melalui cara JSONField Django (pembungkus JSON & JSONB) boleh digunakan untuk memodelkan data separa berstruktur dan cara anda boleh menguatkuasakan skema pada itu data menggunakan Pydantic—pendekatan yang sepatutnya dirasakan semula jadi untuk pembangun web Python.

Takrif jenis fleksibel

Mari kita pertimbangkan sistem yang memproses pembayaran, contohnya jadual Transaksi. Ia akan kelihatan seperti ini:

from django.db import models

class Transaction(models.Model):
    # Other relevant fields...
    payment_method = models.JSONField(default=dict, null=True, blank=True)

tumpuan kami adalah pada medan kaedah_pembayaran. Dalam situasi dunia sebenar, kami akan mempunyai kaedah sedia ada untuk memproses pembayaran:

  • Kad kredit

  • PayPal

  • Beli Sekarang, Bayar Kemudian

  • Cryptocurrency

Sistem kami mesti boleh disesuaikan untuk menyimpan data khusus yang diperlukan oleh setiap kaedah pembayaran sambil mengekalkan struktur yang konsisten dan boleh disahkan.

Kami akan menggunakan Pydantic untuk mentakrifkan skema yang tepat untuk kaedah pembayaran yang berbeza:

from typing import Optional
from pydantic import BaseModel

class CreditCardSchema(BaseModel):
    last_four: str
    expiry_month: int
    expiry_year: int
    cvv: str


class PayPalSchema(BaseModel):
    email: EmailStr
    account_id: str


class CryptoSchema(BaseModel):
    wallet_address: str
    network: Optional[str] = None


class BillingAddressSchema(BaseModel):
    street: str
    city: str
    country: str
    postal_code: str
    state: Optional[str] = None


class PaymentMethodSchema(BaseModel):
    credit_card: Optional[CreditCardSchema] = None
    paypal: Optional[PayPalSchema] = None
    crypto: Optional[CryptoSchema] = None
    billing_address: Optional[BillingAddressSchema] = None

Pendekatan ini menawarkan beberapa faedah penting:

  1. Hanya satu kaedah pembayaran boleh mempunyai nilai bukan nol pada satu masa.

  2. Mudah untuk melanjutkan atau mengubah suai tanpa pemindahan pangkalan data yang rumit.

  3. Memastikan integriti data pada peringkat model.

Untuk menguatkuasakan skema pada medan kaedah_bayaran kami, kami memanfaatkan model Pydantic untuk memastikan bahawa sebarang data yang dihantar ke medan itu sejajar dengan skema yang telah kami tetapkan.

from typing import Optional, Mapping, Type, NoReturn
from pydantic import ValidationError as PydanticValidationError
from django.core.exceptions import ValidationError

def payment_method_validator(value: Optional[dict]) -> Optional[Type[BaseModel] | NoReturn]:
    if value is None:
        return

    if not isinstance(value, Mapping):
        raise TypeError("Payment method must be a dictionary")

    try:
        PaymentMethodSchema(**value)
    except (TypeError, PydanticValidationError) as e:
        raise ValidationError(f"Invalid payment method: {str(e)}")

Di sini, kami melakukan beberapa semakan untuk memastikan data yang memasuki pengesah kami adalah jenis yang betul supaya Pydantic boleh mengesahkannya. Kami tidak melakukan apa-apa untuk nilai yang boleh dibatalkan dan kami menimbulkan ralat jenis jika nilai yang dihantar bukan subkelas jenis Pemetaan, seperti Dict atau OrderedDict.

Apabila kita mencipta contoh model Pydantic menggunakan nilai yang kita masukkan ke dalam pembina. Jika struktur nilai tidak sesuai dengan skema yang ditentukan untuk PaymentMethodSchema, Pydantic akan menimbulkan ralat pengesahan. Contohnya, jika kami menghantar nilai e-mel yang tidak sah untuk medan e-mel dalam PayPalSchema, Pydantic akan menimbulkan ralat pengesahan seperti ini:

ValidationError: 1 validation error for PaymentMethodSchema
paypal.email
  value is not a valid email address: An email address must have an @-sign. [type=value_error, input_value='Check me out on LinkedIn: https://linkedin.com/in/daniel-c-olah', input_type=str]

Kami boleh menguatkuasakan pengesahan ini dalam dua cara:

  1. Kaedah Pengesahan Tersuai

    Semasa proses simpan, kami memanggil fungsi pengesahan untuk memastikan kaedah pembayaran sepadan dengan skema yang dijangkakan.

    from django.db import models
    
    class Transaction(models.Model):
        # ... other fields ...
        payment_method = models.JSONField(null=True, blank=True)
        def save(self, *args, **kwargs):
            # Override save method to include custom validation
            payment_method_validator(self.payment_method)
            super().save(*args, **kwargs)
    

    Walaupun berkesan, pendekatan ini boleh menjadi rumit dan kurang idiomatik dalam Django. Kita juga boleh menggantikan fungsi dengan kaedah kelas yang melakukan perkara yang sama untuk menjadikan kod lebih bersih.

  2. Menggunakan Pengesah Medan

    Kaedah ini memanfaatkan mekanisme pengesahan medan terbina dalam Django:

    from django.db import models
    
    class Transaction(models.Model):
        # Other relevant fields...
        payment_method = models.JSONField(default=dict, null=True, blank=True)
    

    Pendekatan ini mengimbangi fleksibiliti dan kawalan ke atas nilai yang disimpan dalam medan kaedah_pembayaran. Ia membolehkan kami menyesuaikan diri dengan perubahan masa hadapan dalam keperluan tanpa menjejaskan integriti data sedia ada dalam bidang itu. Sebagai contoh, kami boleh memasukkan medan ID Paystack dalam skema Paystack kami. Perubahan ini akan menjadi lancar, kerana kami tidak perlu berurusan dengan migrasi pangkalan data yang rumit.

Kami juga boleh menambah kaedah pay_later pada masa hadapan tanpa sebarang kerumitan. Jenis medan juga boleh berubah dan kami tidak akan menghadapi kekangan migrasi medan pangkalan data, seperti yang dihadapi semasa berhijrah daripada kunci utama integer kepada kunci utama UUID. Anda boleh menyemak kod lengkap di sini untuk memahami konsep sepenuhnya.

Denormalisasi

Denormalisasi melibatkan penduaan data yang disengajakan merentas berbilang dokumen atau koleksi untuk mengoptimumkan prestasi dan kebolehskalaan. Pendekatan ini berbeza dengan normalisasi ketat yang digunakan dalam pangkalan data hubungan tradisional, dan pangkalan data NoSQL telah memainkan peranan penting dalam mempopularkan penyahnormalan dengan memperkenalkan paradigma storan berorientasikan dokumen yang fleksibel.

Pertimbangkan senario e-dagang dengan jadual berasingan untuk produk dan pesanan. Apabila pelanggan membuat pesanan, adalah penting untuk menangkap gambar butiran produk yang disertakan dalam troli. Daripada merujuk rekod produk semasa, yang boleh berubah dari semasa ke semasa disebabkan kemas kini atau pemadaman, kami menyimpan maklumat produk terus dalam pesanan. Ini memastikan pesanan mengekalkan konteks dan integriti asalnya, mencerminkan keadaan sebenar produk pada masa pembelian. Denormalisasi memainkan peranan penting dalam mencapai konsistensi ini.

Satu pendekatan yang mungkin mungkin melibatkan penduaan beberapa medan produk dalam jadual pesanan. Walau bagaimanapun, kaedah ini boleh memperkenalkan cabaran kebolehskalaan dan menjejaskan perpaduan skema pesanan. Penyelesaian yang lebih berkesan ialah mensirikan medan produk yang berkaitan ke dalam struktur JSON, membenarkan pesanan mengekalkan rekod produk yang lengkap tanpa bergantung pada pertanyaan luaran. Kod berikut menggambarkan teknik ini:

from typing import Optional
from pydantic import BaseModel

class CreditCardSchema(BaseModel):
    last_four: str
    expiry_month: int
    expiry_year: int
    cvv: str


class PayPalSchema(BaseModel):
    email: EmailStr
    account_id: str


class CryptoSchema(BaseModel):
    wallet_address: str
    network: Optional[str] = None


class BillingAddressSchema(BaseModel):
    street: str
    city: str
    country: str
    postal_code: str
    state: Optional[str] = None


class PaymentMethodSchema(BaseModel):
    credit_card: Optional[CreditCardSchema] = None
    paypal: Optional[PayPalSchema] = None
    crypto: Optional[CryptoSchema] = None
    billing_address: Optional[BillingAddressSchema] = None

Memandangkan kami telah membincangkan kebanyakan konsep dalam bahagian sebelumnya, anda harus mula menghargai peranan Pydantic dalam semua ini. Dalam contoh di atas, kami menggunakan Pydantic untuk mengesahkan senarai produk yang dipautkan kepada pesanan. Dengan mentakrifkan skema untuk struktur produk, Pydantic memastikan setiap produk yang ditambahkan pada pesanan memenuhi keperluan yang dijangkakan. Jika data yang diberikan tidak mematuhi skema, Pydantic menimbulkan ralat pengesahan.

Menanyakan JSONField dalam Django

Kami boleh menanyakan kekunci JSONField dengan cara yang sama kami melakukan penampilan dalam medan Django. Berikut ialah beberapa contoh berdasarkan kes penggunaan kami.

from typing import Optional, Mapping, Type, NoReturn
from pydantic import ValidationError as PydanticValidationError
from django.core.exceptions import ValidationError

def payment_method_validator(value: Optional[dict]) -> Optional[Type[BaseModel] | NoReturn]:
    if value is None:
        return

    if not isinstance(value, Mapping):
        raise TypeError("Payment method must be a dictionary")

    try:
        PaymentMethodSchema(**value)
    except (TypeError, PydanticValidationError) as e:
        raise ValidationError(f"Invalid payment method: {str(e)}")

Anda boleh menyemak dokumentasi untuk mengetahui lebih lanjut tentang menapis medan JSON.

Kesimpulan

Menggunakan JSON dan JSONB dalam PostgreSQL memberikan fleksibiliti yang hebat untuk bekerja dengan data separa berstruktur dalam pangkalan data hubungan. Alat seperti Pydantic dan JSONField Django membantu menguatkuasakan peraturan untuk struktur data, menjadikannya lebih mudah untuk mengekalkan ketepatan dan menyesuaikan diri dengan perubahan. Walau bagaimanapun, fleksibiliti ini perlu digunakan dengan berhati-hati. Tanpa perancangan yang betul, ia boleh membawa kepada prestasi yang lebih perlahan atau kerumitan yang tidak perlu apabila data anda berubah dari semasa ke semasa.

Dalam Django, pengesah medan hanya dicetuskan apabila full_clean() dipanggil secara eksplisit—ini biasanya berlaku apabila menggunakan Borang Django atau memanggil is_valid() pada penyeri DRF. Untuk butiran lanjut, anda boleh merujuk kepada dokumentasi pengesah Django.

Pendekatan yang lebih maju untuk menangani perkara ini ialah melaksanakan medan Django tersuai yang menyepadukan Pydantic untuk mengendalikan kedua-dua siri dan pengesahan data JSON secara dalaman. Walaupun ini memerlukan artikel khusus, buat masa ini, anda boleh meneroka perpustakaan yang menawarkan penyelesaian siap sedia untuk masalah ini contohnya: django-pydantic-jsonfield

Atas ialah kandungan terperinci Cara Membina Model Data Fleksibel dalam Django dengan JSONField dan Pydantic. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Bagaimana anda menambah elemen ke senarai python?Bagaimana anda menambah elemen ke senarai python?May 04, 2025 am 12:17 AM

ToAppendElementStoapyThonList, useTheAppend () methodforsingleelements, extend () formultipleelements, andInsert () forspecificposition.1) useAppend () foraddingOneElementAttheend.2)

Bagaimana anda membuat senarai python? Beri contoh.Bagaimana anda membuat senarai python? Beri contoh.May 04, 2025 am 12:16 AM

TOCREATEAPYTHONLIST, USESQUAREBRACKETS [] danSeparatateItemSwithCommas.1) listsaredynamicandCanHoldMixedDatypes.2) UseAppend (), mengalih keluar (), danSlicingFormApulation.3)

Bincangkan kes penggunaan dunia sebenar di mana penyimpanan dan pemprosesan data berangka yang cekap adalah kritikal.Bincangkan kes penggunaan dunia sebenar di mana penyimpanan dan pemprosesan data berangka yang cekap adalah kritikal.May 04, 2025 am 12:11 AM

Dalam bidang kewangan, penyelidikan saintifik, penjagaan perubatan dan AI, adalah penting untuk menyimpan dan memproses data berangka dengan cekap. 1) Dalam Kewangan, menggunakan memori yang dipetakan fail dan perpustakaan Numpy dapat meningkatkan kelajuan pemprosesan data dengan ketara. 2) Dalam bidang penyelidikan saintifik, fail HDF5 dioptimumkan untuk penyimpanan data dan pengambilan semula. 3) Dalam penjagaan perubatan, teknologi pengoptimuman pangkalan data seperti pengindeksan dan pembahagian meningkatkan prestasi pertanyaan data. 4) Dalam AI, data sharding dan diedarkan latihan mempercepatkan latihan model. Prestasi dan skalabiliti sistem dapat ditingkatkan dengan ketara dengan memilih alat dan teknologi yang tepat dan menimbang perdagangan antara kelajuan penyimpanan dan pemprosesan.

Bagaimana anda membuat array python? Beri contoh.Bagaimana anda membuat array python? Beri contoh.May 04, 2025 am 12:10 AM

Pythonarraysarecreatedusingthearraymodule, notbuilt-inlikelists.1) importTheArrayModule.2) specifythetypecode, cth., 'I'forintegers.3) Initializewithvalues.arraysofferbettermemoryficiencyficorhomogeneousdatabutflex.

Apakah beberapa alternatif untuk menggunakan garis shebang untuk menentukan penterjemah python?Apakah beberapa alternatif untuk menggunakan garis shebang untuk menentukan penterjemah python?May 04, 2025 am 12:07 AM

Sebagai tambahan kepada garis shebang, terdapat banyak cara untuk menentukan penterjemah python: 1. Gunakan perintah python terus dari baris arahan; 2. Gunakan fail batch atau skrip shell; 3. Gunakan alat binaan seperti membuat atau cmake; 4. Gunakan pelari tugas seperti Invoke. Setiap kaedah mempunyai kelebihan dan kekurangannya, dan penting untuk memilih kaedah yang sesuai dengan keperluan projek.

Bagaimanakah pilihan antara senarai dan tatasusunan memberi kesan kepada prestasi keseluruhan aplikasi Python yang berurusan dengan dataset yang besar?Bagaimanakah pilihan antara senarai dan tatasusunan memberi kesan kepada prestasi keseluruhan aplikasi Python yang berurusan dengan dataset yang besar?May 03, 2025 am 12:11 AM

Forhandlinglargedatasetsinpython, usenumpyarraysforbetterperformance.1) numpyarraysarememory-efisien danfasterfornumumerical.2) mengelakkan yang tidak dapat dipertahankan.3)

Jelaskan bagaimana memori diperuntukkan untuk senarai berbanding tatasusunan dalam Python.Jelaskan bagaimana memori diperuntukkan untuk senarai berbanding tatasusunan dalam Python.May 03, 2025 am 12:10 AM

Inpython, listsusedynamicMemoryAllocationwithover-peruntukan, pemecahan yang tidak dapat dilaksanakan.1) listsallocatemoremoremorythanneedinitial, resizingwhennessary.2) numpyarraysallocateExactMemoreForelements, menawarkanpredictableSabeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeBeat.

Bagaimana anda menentukan jenis data elemen dalam array python?Bagaimana anda menentukan jenis data elemen dalam array python?May 03, 2025 am 12:06 AM

Inpython, YouCansspectHedatypeyFeleMeremodelerernspant.1) Usenpynernrump.1) usenpynerp.dloatp.ploatm64, formor preciscontrolatatypes.

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

SublimeText3 Linux versi baharu

SublimeText3 Linux versi baharu

SublimeText3 Linux versi terkini

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

PhpStorm versi Mac

PhpStorm versi Mac

Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

mPDF

mPDF

mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

Muat turun versi mac editor Atom

Muat turun versi mac editor Atom

Editor sumber terbuka yang paling popular