Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement QuerysetField include tests #77

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

**Features and Improvements**

* Added support for QuerysetField - peterfarrell

## 0.7.1 (2022-02-23)

**Features and Improvements**
Expand Down
80 changes: 77 additions & 3 deletions locale/pt_BR/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-08-17 00:57-0300\n"
"POT-Creation-Date: 2022-12-19 10:30-0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Breno Uchôa <[email protected]>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand All @@ -18,16 +18,90 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"

#: service_objects/fields.py:10
#: service_objects/fields.py:32
#, python-format
msgid "There needs to be at least %(num)d item."
msgid_plural "There needs to be at least %(num)d items."
msgstr[0] "É necessário pelo menos %(num)d item."
msgstr[1] "São necessários pelo menos %(num)d itens."

#: service_objects/fields.py:13
#: service_objects/fields.py:35
#, python-format
msgid "There needs to be at most %(num)d item."
msgid_plural "There needs to be at most %(num)d items."
msgstr[0] "Só pode conter %(num)d item."
msgstr[1] "Só pode conter %(num)d itens."

#: service_objects/fields.py:38
#, python-format
msgid "Input is required. Expected not empty list but got %(values)r."
msgstr ""

#: service_objects/fields.py:108
#, python-format
msgid ""
"%(cls_name)s(%(model_class)r) is invalid. First parameter of ModelField "
"must be either a model or a model name."
msgstr ""
"%(cls_name)s(%(model_class)r) is invalid. First parameter of ModelField "
"must be either a model or a model name."

#: service_objects/fields.py:111
#, python-format
msgid "Objects needs to be of type %(model_class)r"
msgstr "Objects needs to be of type %(model_class)r"

#: service_objects/fields.py:112
msgid "Unsaved objects are not allowed."
msgstr "Unsaved objects are not allowed."

#: service_objects/fields.py:113
#, python-format
msgid "Input is required. Expected model but got %(value)r."
msgstr "Input is required. Expected model but got %(value)r."

#: service_objects/fields.py:190
msgid "Object is not iterable."
msgstr "Object is not iterable."

#: service_objects/fields.py:191
#, python-format
msgid "Input is required expected list of models but got %(values)r."
msgstr "Input is required expected list of models but got %(values)r."

#: service_objects/fields.py:235
#, python-format
msgid ""
"%(cls_name)s(%(model_class)r) is invalid. First parameter of QuerysetField "
"must be either a model or a model name."
msgstr ""
"%(cls_name)s(%(model_class)r) is invalid. First parameter of QuerysetField "
"must be either a model or a model name."

#: service_objects/fields.py:238
#, python-format
msgid "Input is required. Expected queryset but got %(value)r."
msgstr "Input is required. Expected queryset but got %(value)r."

#: service_objects/fields.py:240
#, python-format
msgid "Input is required expected queryset of models but got %(values)r."
msgstr "Input is required expected queryset of models but got %(values)r."

#: service_objects/fields.py:299
#, python-format
msgid "Input is required. Expected dict but got %(value)r."
msgstr "Input is required. Expected dict but got %(value)r."

#: service_objects/fields.py:300
msgid "Input needs to be of type dict."
msgstr "Input needs to be of type dict."

#: service_objects/fields.py:333
#, python-format
msgid "Input is required. Expected list but got %(value)r."
msgstr "Input is required. Expected list but got %(value)r."

#: service_objects/fields.py:334
msgid "Input needs to be of type list."
msgstr "Input needs to be of type list."
76 changes: 58 additions & 18 deletions locale/ru_RU/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2021-03-20 20:35+0700\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-12-19 10:33-0800\n"
"PO-Revision-Date: 2021-03-20 21:05+0700\n"
"Last-Translator: \n"
"Language-Team: \n"
Expand All @@ -15,14 +16,30 @@ msgstr ""
"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
"X-Poedit-SearchPath-0: .\n"

#: service_objects/fields.py:37
#: service_objects/fields.py:32
#, python-format
msgid "There needs to be at least %(num)d item."
msgid_plural "There needs to be at least %(num)d items."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""

#: service_objects/fields.py:35
#, python-format
msgid "There needs to be at most %(num)d item."
msgid_plural "There needs to be at most %(num)d items."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""

#: service_objects/fields.py:38
#, python-format
msgid "Input is required. Expected not empty list but got %(values)r."
msgstr ""
"Входной параметр обязателен. Ожидается непустой список, но получено "
"%(values)r."

#: service_objects/fields.py:107
#: service_objects/fields.py:108
#, python-format
msgid ""
"%(cls_name)s(%(model_class)r) is invalid. First parameter of ModelField "
Expand All @@ -31,48 +48,71 @@ msgstr ""
"%(cls_name)s(%(model_class)r) некорректно. Первый параметр ModelField "
"должен быть моделью или именем модели."

#: service_objects/fields.py:110
#: service_objects/fields.py:111
#, python-format
msgid "Objects needs to be of type %(model_class)r"
msgstr "Объекты должны быть типа %(model_class)r"

#: service_objects/fields.py:111
#: service_objects/fields.py:112
msgid "Unsaved objects are not allowed."
msgstr "Несохраненные объекты не разрешены."

#: service_objects/fields.py:112
#: service_objects/fields.py:113
#, python-format
msgid "Input is required. Expected model but got %(value)r."
msgstr ""
"Входной параметр обязателен. Ожидается модель, но получено %(value)r."
msgstr "Входной параметр обязателен. Ожидается модель, но получено %(value)r."

#: service_objects/fields.py:189
#: service_objects/fields.py:190
msgid "Object is not iterable."
msgstr "Объект не является итерируемым."

#: service_objects/fields.py:190
#: service_objects/fields.py:191
#, python-format
msgid "Input is required expected list of models but got %(values)r."
msgstr ""
"Входной параметр обязателен и ожидается список моделей, но получено "
"%(values)r."

#: service_objects/fields.py:229
#: service_objects/fields.py:235
#, fuzzy, python-format
#| msgid ""
#| "%(cls_name)s(%(model_class)r) is invalid. First parameter of ModelField "
#| "must be either a model or a model name."
msgid ""
"%(cls_name)s(%(model_class)r) is invalid. First parameter of QuerysetField "
"must be either a model or a model name."
msgstr ""
"%(cls_name)s(%(model_class)r) некорректно. Первый параметр ModelField "
"должен быть моделью или именем модели."

#: service_objects/fields.py:238
#, fuzzy, python-format
#| msgid "Input is required. Expected list but got %(value)r."
msgid "Input is required. Expected queryset but got %(value)r."
msgstr "Входной параметр обязателен. Ожидается список, но получено %(value)r."

#: service_objects/fields.py:240
#, fuzzy, python-format
#| msgid "Input is required expected list of models but got %(values)r."
msgid "Input is required expected queryset of models but got %(values)r."
msgstr ""
"Входной параметр обязателен и ожидается список моделей, но получено "
"%(values)r."

#: service_objects/fields.py:299
#, python-format
msgid "Input is required. Expected dict but got %(value)r."
msgstr ""
"Входной параметр обязателен. Ожидается словарь, но получено %(value)r."
msgstr "Входной параметр обязателен. Ожидается словарь, но получено %(value)r."

#: service_objects/fields.py:230
#: service_objects/fields.py:300
msgid "Input needs to be of type dict."
msgstr "Входной параметр должен быть типа словарь."

#: service_objects/fields.py:263
#: service_objects/fields.py:333
#, python-format
msgid "Input is required. Expected list but got %(value)r."
msgstr ""
"Входной параметр обязателен. Ожидается список, но получено %(value)r."
msgstr "Входной параметр обязателен. Ожидается список, но получено %(value)r."

#: service_objects/fields.py:264
#: service_objects/fields.py:334
msgid "Input needs to be of type list."
msgstr "Входной параметр должен быть типа список."
3 changes: 1 addition & 2 deletions makemessages.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,4 @@

django.setup()

management.call_command('makemessages', "--locale=pt_BR", verbosity=0,
interactive=False)
management.call_command('makemessages', "--locale=pt_BR", "--locale=ru_RU", "--ignore=venv/*", verbosity=0)
3 changes: 2 additions & 1 deletion runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
'NAME': ':memory:'
}
},
INSTALLED_APPS=('tests',)
INSTALLED_APPS=('tests',),
DEFAULT_AUTO_FIELD='django.db.models.AutoField',
)
django.setup()

Expand Down
70 changes: 70 additions & 0 deletions service_objects/fields.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django import forms
from django.apps import apps
from django.core.exceptions import ValidationError
from django.db.models.query import QuerySet
from django.utils.translation import ngettext_lazy, gettext_lazy as _


Expand Down Expand Up @@ -210,6 +211,75 @@ def clean(self, values):
return values


class QuerysetField(forms.Field):
"""
A field for :class:`Service` that accepts a queryset of the specified
:class:`Model`::

class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)


class AssociatePeople(Service):
people = QuerysetField(Person)

AssociatePeople.execute({
'people': Users.objects.all()
})

:param model_class: Django :class:`Model` or dotted string of :
class:`Model` name that matches the incoming queryset

"""
error_model_class = _("%(cls_name)s(%(model_class)r) is invalid. First "
"parameter of QuerysetField must be either a model "
"or a model name.")
error_required = _("Input is required. Expected queryset but got "
"%(value)r.")
error_type = _("Input is required expected queryset "
"of models but got %(values)r.")

def __init__(self, model_class, *args, **kwargs):
super().__init__(*args, **kwargs)

try:
model_class._meta.model_name
except AttributeError:
assert isinstance(model_class, str), self.error_model_class % {
'cls_name': self.__class__.__name__,
'model_class': model_class
}

self.model_class = model_class
if isinstance(model_class, str):
label = model_class.split('.')
app_label = ".".join(label[:-1])
model_name = label[-1]
self.model_class = apps.get_model(app_label, model_name)

def clean(self, values):
if self.required:
# Check for queryset and queryset type
if not isinstance(values, QuerySet):
raise ValidationError(self.error_required %
{'value': type(values)})

# Check for queryset and queryset type
if values.model != self.model_class:
raise ValidationError(self.error_model_class % {
'cls_name': self.__class__.__name__,
'model_class': self.model_class
})

if self.required and not values.count():
raise ValidationError(self.error_required % {
'value': type(values)
})

return values


class DictField(forms.Field):
"""
A field for :class:`Service` that accepts a dictionary:
Expand Down
Loading