[解決済み] Django REST フレームワークのカスタムフィールドの検証
2022-12-16 12:16:20
質問
あるモデルに対してカスタムバリデーションを作成しようとしています。
start_date
がその
end_date
の前にあり、それは不可能に近いことが証明されています。
私が試したもの。
-
組み込みの Django バリデータ: これをチェックするものはありません。
-
を自分で書くと、こんな感じ。
def validate_date(self): if self.start_date < self.end_date: raise serializers.ValidationError("End date must be after start date.")
そのコードのビットをSerializerクラス(そしてモデル)に追加しましたが、どちらの場所でも呼び出されることはないようです。
また、私は この のコードも見つけましたが、私のメソッドにどのように統合すればよいのかわかりません。
私のモデルです。
class MyModel(models.Model):
created = models.DateTimeField(auto_now_add=True)
relation_model = models.ForeignKey(RelationModel, related_name="mymodels")
priority = models.IntegerField(
validators = [validators.MinValueValidator(0), validators.MaxValueValidator(100)])
start_date = models.DateField()
end_date = models.DateField()
@property
def is_active(self):
today = datetime.date.today()
return (today >= self.start_date) and (today <= self.end_date)
def __unicode__(self):
...
class Meta:
unique_together = ('relation_model', 'priority', 'start_date', 'end_date')
参考までに、他のバリデーションはすべて動作します!
私のシリアライザーです。
class MyModelSerializer(serializers.ModelSerializer):
relation_model = RelationModelSerializer
is_active = serializers.Field(source='is_active')
def validate_date(self):
if self.start_date > self.end_date:
raise serializers.ValidationError("End date must be after start date.")
class Meta:
model = MyModel
fields = (
'id', 'relation_model', 'priority', 'start_date', 'end_date', 'is_active'
)
私の見解です。
class MyModelList(generics.ListCreateAPIView):
permission_classes = (IsAdminUser,)
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
ordering = ('priority')
どのように解決するのですか?
オブジェクト・ワイド・バリデーションを使用する必要があります (
validate()
) を使うべきです。
validate_date
は決して呼び出されないので
date
はシリアライザーのフィールドではないので、呼び出されることはありません。
ドキュメントから
:
class MySerializer(serializers.ModelSerializer):
def validate(self, data):
"""
Check that the start is before the stop.
"""
if data['start_date'] > data['end_date']:
raise serializers.ValidationError("finish must occur after start")
return data
Michel Sabchuk が提案したように、バリデーションエラーを
end_date
フィールドに追加することができます。
class MySerializer(serializers.ModelSerializer):
def validate(self, data):
"""
Check that the start is before the stop.
"""
if data['start_date'] > data['end_date']:
raise serializers.ValidationError({"end_date": "finish must occur after start"})
return data
もう一つの可能性は、バリデータを作成することです。のコードに基づいて作成しました。
UniqueTogetherValidator
:
from rest_framework.utils.representation import smart_repr
class DateBeforeValidator:
"""
Validator for checking if a start date is before an end date field.
Implementation based on `UniqueTogetherValidator` of Django Rest Framework.
"""
message = _('{start_date_field} should be before {end_date_field}.')
def __init__(self, start_date_field="start_date", end_date_field="end_date", message=None):
self.start_date_field = start_date_field
self.end_date_field = end_date_field
self.message = message or self.message
def __call__(self, attrs):
if attrs[self.start_date_field] > attrs[self.end_date_field]:
message = self.message.format(
start_date_field=self.start_date_field,
end_date_field=self.end_date_field,
)
# Replace the following line with
# raise serializers.ValidationError(
# {self.end_date_field: message},
# code='date_before',
# )
# if you want to raise the error on the field level
raise serializers.ValidationError(message, code='date_before')
def __repr__(self):
return '<%s(start_date_field=%s, end_date_field=%s)>' % (
self.__class__.__name__,
smart_repr(self.start_date_field),
smart_repr(self.end_date_field)
)
class MySerializer(serializers.ModelSerializer):
class Meta:
# If your start/end date fields have another name give them as kwargs tot the
# validator:
# DateBeforeValidator(
# start_date_field="my_start_date",
# end_date_field="my_end_date",
# )
validators = [DateBeforeValidator()]
DRF3.0以前は、モデルのクリーン関数に追加することもできましたが、DRF3.0ではもう呼び出されません。
class MyModel(models.Model):
start_date = models.DateField()
end_date = models.DateField()
def clean(self):
if self.end_date < self.start_date:
raise ValidationError("End date must be after start date.")
関連
-
Djangoキャッシュの説明
-
[解決済み] Django のカスタムフィールドで User モデルを拡張する
-
[解決済み】Djangoでnull=Trueとblank=Trueの違いは何ですか?
-
[解決済み] Django restフレームワーク、同じModelViewSetで異なるシリアライザーを使用する。
-
[解決済み] Django の修正 管理者の複数形
-
[解決済み] Django REST フレームワーク: 非モデルシリアライザー
-
[解決済み] Django Rest Frameworkを使用して、関連するモデルフィールドを含めるにはどうすればよいですか?
-
[解決済み] Django Southを使用して移行履歴をリセットするための推奨される方法は何ですか?
-
[解決済み] django-tastypie と djangorestframework の違いは何ですか?[クローズド]
-
[解決済み] Django Rest フレームワーク。フィールドのサブセットを動的に返す
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Django でチェックボックスの値を取得する方法
-
Django ForeignKey逆引きクエリにおけるfilterと_setの効率比較
-
[解決済み] Django のフォームで、あるフィールドを編集できないように readonly (または disabled) にするにはどうしたらいいですか?
-
[解決済み] RuntimeWarning: DateTimeFieldがナイーブなdatetimeを受信した
-
[解決済み] Django REST Framework: ModelSerializerに追加フィールドを追加する
-
[解決済み] Django - 外部キーのプロパティでフィルタリングする
-
[解決済み] 学習に適したオープンソースのdjangoプロジェクト【非公開
-
[解決済み] Django の {% url %} テンプレートタグでクエリパラメータを渡すことは可能でしょうか?
-
[解決済み] Django の DoesNotExist 例外はどのようにインポートしますか?
-
[解決済み] Django の日付テンプレートのデフォルトフォーマットを変更するには?