Rumah pembangunan bahagian belakang Tutorial Python Cara Membina Model Data Fleksibel dalam Django dengan JSONField dan Pydantic

Cara Membina Model Data Fleksibel dalam Django dengan JSONField dan Pydantic

Dec 31, 2024 pm 06:13 PM

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)
Salin selepas log masuk
Salin selepas log masuk

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
Salin selepas log masuk
Salin selepas log masuk

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)}")
Salin selepas log masuk
Salin selepas log masuk

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]
Salin selepas log masuk

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)
    
    Salin selepas log masuk

    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)
    
    Salin selepas log masuk
    Salin selepas log masuk

    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
Salin selepas log masuk
Salin selepas log masuk

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)}")
Salin selepas log masuk
Salin selepas log masuk

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 Laman Web ini
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

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

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Python vs C: Aplikasi dan kes penggunaan dibandingkan Python vs C: Aplikasi dan kes penggunaan dibandingkan Apr 12, 2025 am 12:01 AM

Python sesuai untuk sains data, pembangunan web dan tugas automasi, manakala C sesuai untuk pengaturcaraan sistem, pembangunan permainan dan sistem tertanam. Python terkenal dengan kesederhanaan dan ekosistem yang kuat, manakala C dikenali dengan keupayaan kawalan dan keupayaan kawalan yang mendasari.

Berapa banyak python yang boleh anda pelajari dalam 2 jam? Berapa banyak python yang boleh anda pelajari dalam 2 jam? Apr 09, 2025 pm 04:33 PM

Anda boleh mempelajari asas -asas Python dalam masa dua jam. 1. Belajar pembolehubah dan jenis data, 2. Struktur kawalan induk seperti jika pernyataan dan gelung, 3 memahami definisi dan penggunaan fungsi. Ini akan membantu anda mula menulis program python mudah.

Python: Permainan, GUI, dan banyak lagi Python: Permainan, GUI, dan banyak lagi Apr 13, 2025 am 12:14 AM

Python cemerlang dalam permainan dan pembangunan GUI. 1) Pembangunan permainan menggunakan pygame, menyediakan lukisan, audio dan fungsi lain, yang sesuai untuk membuat permainan 2D. 2) Pembangunan GUI boleh memilih tkinter atau pyqt. TKInter adalah mudah dan mudah digunakan, PYQT mempunyai fungsi yang kaya dan sesuai untuk pembangunan profesional.

Rancangan Python 2 jam: Pendekatan yang realistik Rancangan Python 2 jam: Pendekatan yang realistik Apr 11, 2025 am 12:04 AM

Anda boleh mempelajari konsep pengaturcaraan asas dan kemahiran Python dalam masa 2 jam. 1. Belajar Pembolehubah dan Jenis Data, 2.

Python: meneroka aplikasi utamanya Python: meneroka aplikasi utamanya Apr 10, 2025 am 09:41 AM

Python digunakan secara meluas dalam bidang pembangunan web, sains data, pembelajaran mesin, automasi dan skrip. 1) Dalam pembangunan web, kerangka Django dan Flask memudahkan proses pembangunan. 2) Dalam bidang sains data dan pembelajaran mesin, numpy, panda, scikit-learn dan perpustakaan tensorflow memberikan sokongan yang kuat. 3) Dari segi automasi dan skrip, Python sesuai untuk tugas -tugas seperti ujian automatik dan pengurusan sistem.

Python vs C: Lengkung pembelajaran dan kemudahan penggunaan Python vs C: Lengkung pembelajaran dan kemudahan penggunaan Apr 19, 2025 am 12:20 AM

Python lebih mudah dipelajari dan digunakan, manakala C lebih kuat tetapi kompleks. 1. Sintaks Python adalah ringkas dan sesuai untuk pemula. Penaipan dinamik dan pengurusan memori automatik menjadikannya mudah digunakan, tetapi boleh menyebabkan kesilapan runtime. 2.C menyediakan kawalan peringkat rendah dan ciri-ciri canggih, sesuai untuk aplikasi berprestasi tinggi, tetapi mempunyai ambang pembelajaran yang tinggi dan memerlukan memori manual dan pengurusan keselamatan jenis.

Python dan Masa: Memanfaatkan masa belajar anda Python dan Masa: Memanfaatkan masa belajar anda Apr 14, 2025 am 12:02 AM

Untuk memaksimumkan kecekapan pembelajaran Python dalam masa yang terhad, anda boleh menggunakan modul, masa, dan modul Python. 1. Modul DateTime digunakan untuk merakam dan merancang masa pembelajaran. 2. Modul Masa membantu menetapkan kajian dan masa rehat. 3. Modul Jadual secara automatik mengatur tugas pembelajaran mingguan.

Python: Automasi, skrip, dan pengurusan tugas Python: Automasi, skrip, dan pengurusan tugas Apr 16, 2025 am 12:14 AM

Python cemerlang dalam automasi, skrip, dan pengurusan tugas. 1) Automasi: Sandaran fail direalisasikan melalui perpustakaan standard seperti OS dan Shutil. 2) Penulisan Skrip: Gunakan Perpustakaan Psutil untuk memantau sumber sistem. 3) Pengurusan Tugas: Gunakan perpustakaan jadual untuk menjadualkan tugas. Kemudahan penggunaan Python dan sokongan perpustakaan yang kaya menjadikannya alat pilihan di kawasan ini.

See all articles