peewee-validates
peewee-validates copied to clipboard
Problems with ManyModelChoiceField validation.
Hello! I have model like this:
class TestModel(peewee.Model):
foo = peewee.ForeignKeyField(ModelOne)
bar = peewee.ForeignKeyField(ModelTwo)
class Meta:
indexes = (
(("foo", "bar"), True),
)
And when i use <select multiple> i have a mysql error like this:
ERROR 1241 (21000): Operand should contain 1 column(s)
So, i'd made some research and find the problem.
def perform_index_validation(self, data):
"""
Validate any unique indexes specified on the model.
This should happen after all the normal fields have been validated.
This can add error messages to multiple fields.
:return: None
"""
# Build a list of dict containing query values for each unique index.
index_data = []
for columns, unique in self.instance._meta.indexes:
if not unique:
continue
index_data.append({col: data.get(col, None) for col in columns})
# Then query for each unique index to see if the value is unique.
for index in index_data:
_query = self.instance.filter(**index)_
# If we have a primary key, need to exclude the current record from the check.
if self.pk_field and self.pk_value:
query = query.where(~(self.pk_field == self.pk_value))
if query.count():
err = ValidationError('index', fields=str.join(', ', index.keys()))
for col in index.keys():
self.add_error(col, err)
query = self.instance.filter(**index) generate invalid sql query:
Count(*)
FROM testmodel AS t1
INNER JOIN modelone AS t2 ON (t1.foo_id = t2.id)
INNER JOIN modeltwo AS t3 ON (t1.bar_id = t3.id)
WHERE ((t1.foo_id = 7) AND (t1.bar_id = (2, 4)));
(t1.bar_id = (2, 4))) - this is a problem sql
I know, this is a peewee orm error, but you can solve this problem on your side like this:
def perform_index_validation(self, data):
"""
Validate any unique indexes specified on the model.
This should happen after all the normal fields have been validated.
This can add error messages to multiple fields.
:return: None
"""
# Build a list of dict containing query values for each unique index.
index_data = []
for columns, unique in self.instance._meta.indexes:
if not unique:
continue
index_data.append({col: data.get(col, None) for col in columns})
# Then query for each unique index to see if the value is unique.
for index in index_data:
new_index = {}
for k, v in index.items():
if issubclass(type(v), Iterable):
k = '%s__in' % k
new_index[k] = v
query = self.instance.filter(**new_index)
# If we have a primary key, need to exclude the current record from the check.
if self.pk_field and self.pk_value:
if issubclass(type(self.pk_value), Iterable):
query = query.where(~(self.pk_field >> self.pk_value))
else:
query = query.where(~(self.pk_field == self.pk_value))
if query.count():
err = ValidationError('index', fields=str.join(', ', index.keys()))
for col in index.keys():
self.add_error(col, err)
p.s. Your product wery handy. Thank you for it!