I see, I think you'll need to wrap the inner Q in an ExpressionWrapper[0]
That would be
CheckConstraint(check=Q(is_on_sale=ExpressionWrapper(Q(price__lt=F('full_price')),
output_field=models.BooleanField())))
That involves a lot of boilerplate though and it ought to work without all
of it so I'd submit an optimization ticket
to allow direct usage of Q objects for boolean field lookup right hand sides
Cheers,
Simon
https://docs.djangoproject.com/en/3.0/ref/models/expressions/#django.db.models.ExpressionWrapper
Le lundi 27 janvier 2020 14:32:24 UTC-5, Peter Law a écrit :
>
> Hi Simon,
>
> Thanks for your response.
>
> I did try that, however unfortunately I get an error when running the
> migration:
>
> django.core.exceptions.ValidationError: ["'(AND:
> <django.db.models.lookups.LessThan object at 0x7fcc49998a20>)' value must
> be either True or False."]
>
> I'm using Django 2.2 LTS though testing this in 3.0 unfortunately errors
> in the same way.
>
> I think the issue with this spelling is that a `models.Q` isn't expecting
> to be passed another `models.Q` as a value. I think ideally it would want
> an expression there, which a `models.F` is closest to, however using a
> `models.F` relation there also doesn't work (see my response to Stephen's
> suggestion).
>
> Thanks,
> Peter
>
> On Monday, 27 January 2020 18:23:28 UTC, Simon Charette wrote:
>>
>> Did you try
>>
>> class Item(Model):
>> price = DecimalField()
>> full_price = DecimalField()
>> is_on_sale = BooleanField()
>>
>> class Meta:
>> constraints = [
>>
>> CheckConstraint(check=Q(is_on_sale=Q(price__lt=F('full_price'))))
>> ]
>>
>> I haven't tried it myself but I would expect it to work on Django 3.0.
>>
>> Cheers,
>> Simon
>>
>> Le lundi 27 janvier 2020 12:47:37 UTC-5, Peter Law a écrit :
>>>
>>> Hi,
>>>
>>> Thanks for adding support for check constraints in Django 2.2, it's
>>> great to be able to move constraints into the model definitions.
>>>
>>> I've been trying to work out how to express a constraint which
>>> validates that the value of one field expresses a relation between two
>>> other fields, but can't find a nice way to do so.
>>>
>>> I've read through the docs and also found
>>> https://groups.google.com/d/topic/django-users/6Olh5V1b7Us/discussion,
>>> but haven't found a concise spelling.
>>>
>>> I've got a model like:
>>>
>>> ```
>>> class Item(Model):
>>> price = DecimalField()
>>> full_price = DecimalField()
>>> is_on_sale = BooleanField()
>>> ```
>>>
>>> I'd like to be able to express neatly that the `is_on_sale` boolean be
>>> true only when `price < full_price`.
>>> In Postgres I can express this as:
>>>
>>> ```
>>> ALTER TABLE item
>>> ADD CONSTRAINT is_on_sale_check
>>> CHECK (is_on_sale = (price < full_price))
>>> ```
>>>
>>> However in Django I can't find a way to express this directly.
>>>
>>> I did find a long spelling which essentially checks the True case and
>>> the False case explicitly and then ORs them together, however it's
>>> several lines of `models.Q` combinations and not at all clear about
>>> what the code is trying to achieve.
>>>
>>> Is there a concise way to do this sort of constraint? If not, would it
>>> be possible for Django to add support for it?
>>>
>>> Thanks,
>>> Peter
>>>
>>
--
You received this message because you are subscribed to the Google Groups
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/5d9488a8-7e6d-4a96-b009-fd94feb9df86%40googlegroups.com.