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

Problems with ManyModelChoiceField validation. #5

Open
LolusKekus opened this issue Aug 30, 2017 · 0 comments
Open

Problems with ManyModelChoiceField validation. #5

LolusKekus opened this issue Aug 30, 2017 · 0 comments

Comments

@LolusKekus
Copy link

LolusKekus commented Aug 30, 2017

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant