mirror of
https://github.com/SectorLabs/django-localized-fields.git
synced 2025-10-29 18:18:57 +03:00
Merge pull request #29 from MELScience/required
Improved functionality of required parameter
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import json
|
||||
|
||||
from typing import Union
|
||||
from typing import Union, List
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.utils import IntegrityError
|
||||
@@ -27,10 +27,17 @@ class LocalizedField(HStoreField):
|
||||
# The descriptor to use for accessing the attribute off of the class.
|
||||
descriptor_class = LocalizedValueDescriptor
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, *args, required: Union[bool, List[str]]=None, **kwargs):
|
||||
"""Initializes a new instance of :see:LocalizedField."""
|
||||
|
||||
super(LocalizedField, self).__init__(*args, **kwargs)
|
||||
super(LocalizedField, self).__init__(*args, required=required, **kwargs)
|
||||
|
||||
if (self.required is None and self.blank) or self.required is False:
|
||||
self.required = []
|
||||
elif self.required is None and not self.blank:
|
||||
self.required = [settings.LANGUAGE_CODE]
|
||||
elif self.required is True:
|
||||
self.required = [lang_code for lang_code, _ in settings.LANGUAGES]
|
||||
|
||||
def contribute_to_class(self, model, name, **kwargs):
|
||||
"""Adds this field to the specifed model.
|
||||
@@ -170,9 +177,6 @@ class LocalizedField(HStoreField):
|
||||
# are any of the language fiels None/empty?
|
||||
is_all_null = True
|
||||
for lang_code, _ in settings.LANGUAGES:
|
||||
# NOTE(seroy): use check for None, instead of
|
||||
# `bool(value.get(lang_code))==True` condition, cause in this way
|
||||
# we can not save '' value
|
||||
if value.get(lang_code) is not None:
|
||||
is_all_null = False
|
||||
break
|
||||
@@ -185,8 +189,8 @@ class LocalizedField(HStoreField):
|
||||
return value
|
||||
|
||||
def validate(self, value: LocalizedValue, *_):
|
||||
"""Validates that the value for the primary language
|
||||
has been filled in.
|
||||
"""Validates that the values has been filled in for all required
|
||||
languages
|
||||
|
||||
Exceptions are raises in order to notify the user
|
||||
of invalid values.
|
||||
@@ -199,36 +203,19 @@ class LocalizedField(HStoreField):
|
||||
if self.null:
|
||||
return
|
||||
|
||||
primary_lang_val = getattr(value, settings.LANGUAGE_CODE)
|
||||
for lang in self.required:
|
||||
lang_val = getattr(value, settings.LANGUAGE_CODE)
|
||||
|
||||
# NOTE(seroy): use check for None, instead of `not primary_lang_val`
|
||||
# condition, cause in this way we can not save '' value
|
||||
if primary_lang_val is None:
|
||||
raise IntegrityError(
|
||||
'null value in column "%s.%s" violates not-null constraint' % (
|
||||
self.name,
|
||||
settings.LANGUAGE_CODE
|
||||
)
|
||||
)
|
||||
if lang_val is None:
|
||||
raise IntegrityError('null value in column "%s.%s" violates '
|
||||
'not-null constraint' % (self.name, lang))
|
||||
|
||||
def formfield(self, **kwargs):
|
||||
"""Gets the form field associated with this field."""
|
||||
|
||||
defaults = {
|
||||
'form_class': LocalizedFieldForm
|
||||
}
|
||||
|
||||
defaults = dict(
|
||||
form_class=LocalizedFieldForm,
|
||||
required=False if self.blank else self.required
|
||||
)
|
||||
defaults.update(kwargs)
|
||||
return super().formfield(**defaults)
|
||||
|
||||
def deconstruct(self):
|
||||
"""Gets the values to pass to :see:__init__ when
|
||||
re-creating this object."""
|
||||
|
||||
name, path, args, kwargs = super(
|
||||
LocalizedField, self).deconstruct()
|
||||
|
||||
if self.uniqueness:
|
||||
kwargs['uniqueness'] = self.uniqueness
|
||||
|
||||
return name, path, args, kwargs
|
||||
|
||||
@@ -146,8 +146,6 @@ class LocalizedFileField(LocalizedField):
|
||||
|
||||
def formfield(self, **kwargs):
|
||||
defaults = {'form_class': LocalizedFileFieldForm}
|
||||
if 'initial' in kwargs:
|
||||
defaults['required'] = False
|
||||
defaults.update(kwargs)
|
||||
return super().formfield(**defaults)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import List
|
||||
from typing import List, Union
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
@@ -19,28 +19,29 @@ class LocalizedFieldForm(forms.MultiValueField):
|
||||
field_class = forms.fields.CharField
|
||||
value_class = LocalizedValue
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, *args, required: Union[bool, List[str]]=False, **kwargs):
|
||||
"""Initializes a new instance of :see:LocalizedFieldForm."""
|
||||
|
||||
fields = []
|
||||
|
||||
for lang_code, _ in settings.LANGUAGES:
|
||||
field_options = {'required': False}
|
||||
|
||||
if lang_code == settings.LANGUAGE_CODE:
|
||||
field_options['required'] = kwargs.get('required', True)
|
||||
|
||||
field_options['label'] = lang_code
|
||||
field_options = dict(
|
||||
required=required if type(required) is bool else (lang_code in
|
||||
required),
|
||||
label=lang_code
|
||||
)
|
||||
fields.append(self.field_class(**field_options))
|
||||
|
||||
super(LocalizedFieldForm, self).__init__(
|
||||
fields,
|
||||
required=required if type(required) is bool else True,
|
||||
require_all_fields=False,
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
# set 'required' attribute for each widget separately
|
||||
for f, w in zip(self.fields, self.widget.widgets):
|
||||
w.is_required = f.required
|
||||
for field, widget in zip(self.fields, self.widget.widgets):
|
||||
widget.is_required = field.required
|
||||
|
||||
def compress(self, value: List[str]) -> value_class:
|
||||
"""Compresses the values from individual fields
|
||||
|
||||
Reference in New Issue
Block a user