Что стоит за механизмом моделей и полей Джанго? - PullRequest
1 голос
/ 09 июля 2019

Что такое механизм Django / Python, стоящий за моделью / полевой частью Django фреймворка?

Если быть точным, я ищу подсказку о том, как Django анализирует (?) Определение класса и затем знает, какие поля обязательны для заполнения?

from django.db import models


class Car(models.Model):
    name = models.CharField(max_length=255, null=True, blank=True)
    year_of_production = models.DateField(null=True)
    # the rest of fields...

Я думаю, что тот же механизм стоит за DjangoФреймворк форм или сериализаторы DRF.Я проверил репо этих проектов, но все еще не могу найти разумную отправную точку.

В моем вопросе архитектурная проблема.Я думаю, что мне нужно реализовать нечто похожее на этот механизм:

class Field:
    def __init__(self, label: str, required: bool = True, **kwargs):
        self.label, self.required = label, required


class CharField(Field):
    def __init__(self, max_length: int, **kwargs):
        self.max_length = max_length
        super().__init__(**kwargs)

class DateField(Field):
    ...

class BooleanField(Field):
    ...

class Model:
    # the mechanisms I do not understand

class MyModelInstance(Model):
    name = CharField(...)
    # etc.    

Мне нужно действительно простое решение, которое знает, что это поле обязательно для заполнения.Но, как я уже говорил ранее, я не настолько продвинут, и я был бы очень признателен за любые подсказки.

Редактировать: Я думаю, что я ищу что-то вроде механизма форм Django, а не модели / поля.

1 Ответ

0 голосов
/ 09 июля 2019

Формы и модели следуют той же базовой идее, но формы немного проще, поэтому давайте отправимся туда.

Метакласс DeclarativeFieldsMetaclass используется в Form.
Он собирает field s во время объявления (с некоторым обходом MRO, но основная идея состоит в том, чтобы просто посмотреть, являются ли они isinstance(x, Field)), удаляет их из объявления конкретного классаи перемещает их в cls.base_fields (где cls - это класс, который вы объявляете).

Когда вы создаете экземпляр вашего нового Form, этот код здесь deepcopies self.base_fields (что на уровне класса, но это не относится к делу) в self.fields (так что вы можете безопасно изменять self.fields в каждом экземпляре формы, не влияя на другие запросы)..

Кроме того, если вы хотите, чтобы собираемая вещь требовала полей в отдельном атрибуте, это было бы что-то вроде

cls.required_fields = {f for f in cls.base_fields if f.required}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...