簡體   English   中英

檢查 Django 中是否存在 model 字段

[英]Check if model field exists in Django

這是我在models.py中提出的解決方案:

from django.db import models

@classmethod
def model_field_exists(cls, field):
    try:
        cls._meta.get_field(field)
        return True
    except models.FieldDoesNotExist:
        return False

models.Model.field_exists = model_field_exists

並像這樣使用它:

Post.field_exists('title') # > True or False

問題出在外鍵上,我的帖子 model 屬於一個類別,此檢查有效:

Post.field_exists('category') # > True

但是這個沒有:

Post.field_exists('category_id') # > False

這是 db 中的實際字段名稱,我需要像這樣檢查它。 如何在 django 中做到這一點?

hasattr(cls,field)在所有情況下都不起作用,例如使用mixins的情況。 安全測試是:

            try:
                model._meta.get_field(field)
                .. do stuff here
            except FieldDoesNotExist:
                pass

要么

            field = None
            try:
                field = model._meta.get_field(field)
            except FieldDoesNotExist:
                pass

            if field:
              .. do stuff here

如果該字段不存在,您可以使用getattr返回默認值。如下所示

getattr(table, field, False)

您的“category_id”字段是https://docs.djangoproject.com/en/1.10/ref/models/meta/術語中的隱藏字段。 get_field無法檢索它。

也許循環遍歷所有字段並檢查其名稱; get_fields可以返回隱藏字段:

for field in cls._meta.get_fields(include_hidden=True):
    if field.name == field:
        return True
return False

如果您需要關心其db_column已從其默認值更改的字段,您也可以測試field.db_column(但如果未明確設置則未設置)。

但是這個沒有:

Post.field_exists('category_id')#> False

這是db中的實際字段名稱,我需要像這樣檢查它。 我怎么能在django做到這一點?

除了_id部分之外的所有事情的情況在另一個答案中得到了充分的回答。 為了處理_id案例, 除了適當處理這些案例的答案之外 ,你基本上還需要一個特殊的條件。 類似這樣的東西:

if field_name.endswith('_id'):
    try:
        field = model._meta.get_field(field_name.strip('_id'))
    except FieldDoesNotExist:
        return False
    if not f.is_relation:
        return False
    return True

需要進行額外的檢查以確保字段減去_id返回ForeignKey,而不是恰好具有相同名稱的其他類型的字段,這意味着模型上的name_id字段無效。

你為什么需要這個? 對象關系映射器的概念是用於描述/定義數據庫的類。 因此,如果您想測試模型的類型,您應該使用isinstance如下所示:

if isinstance(model, Post):
    # model is a Post, Post has a publish()
    model.publish()
elif isinstance(model, Comment):
    # model is a Comment, Comment has a foo()
    model.foo()

您的模型定義定義了您的架構。 沒有理由必須測試場的存在。 如果有,您可能沒有通過使用setattr分配字段來遵循最佳實踐?

YourModelName.objects.filter(YourModelField=TheFieldToCheck).exists()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM