Re: Use of TIME_INPUT_FORMATS in TimeField

2024-03-05 Thread David Sanders
Define TIME_INPUT_FORMATS in your local formats.py setup as per:
https://docs.djangoproject.com/en/5.0/topics/i18n/formatting/#creating-custom-format-files

On Tue, 5 Mar 2024 at 18:43, Arthur Pemberton  wrote:

> The documentation (
> https://docs.djangoproject.com/en/5.0/ref/forms/fields/#timefield) says
> that " the default input formats are taken from the active locale format
> TIME_INPUT_FORMATS key, or from TIME_INPUT_FORMATS
> 
> if localization is disabled". However, neither my reading of the code, or
> my actual experience shows settings.TIME_INPUT_FORMATS ever being used,
> even with "USE_I18N = False"
>
> TimeField gets the formats from `input_formats =
> formats.get_format_lazy("TIME_INPUT_FORMATS")` which is a lazy version of
> `formats.get_format` -- the documentation of which says "If use_l10n is
> provided and is not None, it forces the value to be localized (or not),
> otherwise it's always localized."
>
> so even with "USE_I18N = False" settings.TIME_INPUT_FORMATS seems to be
> ignored.
>
> How does one use settings.TIME_INPUT_FORMATS ?
>
> Arthur Pemberton
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CA%2BX4dQRAjfSJnAK9iZ%3DhJMkN%2BTfoShX6%2BNRsjM0oMF6jGDSuZg%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-5Vb6K4HQjVbcr1aQGCdozoHkA%2B2Q4Vczp8L63ROX%2BDtQ%40mail.gmail.com.


Re: Potential bug with how Value works with Django ORM queries

2023-10-26 Thread David Sanders
Hi Nitin,

Not sure what db you're using but will explain assuming PG.

In this particular example, Django uses the `->` operator which requires 
that we compare jsonb types.  The `__in=("Program1", "Program2")` is 
converted to jsonb via `DatabaseOperations.adapt_json_value()` where as 
`Value()` isn't.

`Value()` assumes the type of the argument passed in – in this case `str` – 
unless you pass a second argument, `output_field`. Specifying 
`output_field=JSONField()` will cause the ORM to pass these values to 
`DatabaseOperations.adapt_json_value()`.

So this will work:

`Study.objects.filter(study_data__protocol__general__program_name__in=(Value("Program1",
 
output_field=JSONField()), ...))`

Regards
David

On Thursday, 26 October 2023 at 03:39:08 UTC+11 Nitin Chaudhary wrote:

> Hi 
> I recently came across a very interesting scenario. I have a JSON Field 
> which I want to query on. I was trying to do some performance 
> optimizations  and came across this
>
> If I query a non-JSON field like this:
> Study.objects.all().filter(study_id__in=[Value("Tes1"),Value("Test2")])
> and 
> Study.objects.all().filter(study_id__in=["Test1","Test2"])
> both of these queries return the same results
>
> but if I try performing the same on a JSONField
> Study.objects.all().filter(study_data__protocol__general__program_name__in=(Value("Program1"),
>  
> Value("Program2")))
> results in
> DataError: invalid input syntax for type json
> LINE 1: ...> ARRAY['protocol','general','program_name']) IN ('Prog ...
>  ^
> DETAIL:  Token "Program1" is invalid.
> CONTEXT:  JSON data, line 1: Program1
>
> and 
>
> Study.objects.all().filter(study_data__protocol__general__program_name__in=("Program1","Program2"))
> works fine.
>
> I am not sure if this is a potential bug with Django or is like this by 
> design. Would really appreciate if someone can explain this behavior 
> difference.
>
> Cheers
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/95511868-4a44-4757-a992-b4e17c716668n%40googlegroups.com.


Re: Proposing the removal of Oracle from the Django supported backend databases

2023-08-27 Thread David Sanders
I posted a thread a while back about the latest version of Oracle 23c which
appears to add support for a few things that would fix some of the
workarounds we have in the ORM (eg boolean expressions). I know dropping
19c is a long way off but at least the future is looking brighter 🌟

On Wed, 9 Aug 2023, 6:40 pm Carlton Gibson, 
wrote:

> Thanks for raising this Paolo. It's good to discuss, even if we maintain
> the status quo.
>
> I think this will come to a head when Mariusz steps away. It's been him
> that's kept it going the last few years, and I'm not at all sure that we
> have another currently active contributor that's an Oracle expert. (Perhaps
> we do... 🤔)
>
> It's good to see Chris' comment that Oracle wish to contribute themselves,
> but if that doesn't materialise, we're going to need to claim *force
> majeure*.
>
> Q: Are we sure we can maintain Oracle without Mariusz? What does that look
> like? If not, we need to make plans for something else.
>
>
> FWIW: If possible I'd like to keep Oracle support if we can — it's good
> for the ORM.
> (If we could see a way of it being maintainable, I'd have us add SQL
> Server in core too — but I don't think that is feasible given the state of
> play today).
>
>
> The difference with Windows (of course) is that we have lots of
> contributors using it.
>
>
> Kind Regards,
>
> Carlton
>
> On Fri, 4 Aug 2023 at 15:19, Paolo Melchiorre 
> wrote:
>
>> Hi Mariusz,
>>
>> On Thu, Aug 3, 2023 at 8:47 PM Mariusz Felisiak
>>  wrote:
>> > I'm quite surprised that you've started a new thread for something that
>> was already discussed, you could always add a comment to the existing
>> thread e.g.
>> https://groups.google.com/g/django-developers/c/dg8BUVHKOo4/m/5uFVmdWCAwAJ
>>
>> I was not aware of this thread, thanks for linking it.
>>
>> >> I wanted to share the frustration of seeing yet another great new ORM
>> feature blocked due to Oracle compatibility:
>> https://github.com/django/django/pull/16417
>> > I'm not sure how you reached this conclusion. This is not blocked due
>> because of Oracle compatibility. I will review it and try to merge it
>> before the Django 5.0 feature freeze. You have to be patient, it has
>> nothing to do with Oracle
>>
>> It was not my intention to push you into reviewing this PR given how
>> much you already do. But it seems to me that without Oracle
>> compatibility this functionality would have been ready for a long
>> time. However, this reflection of mine was born after seeing the
>> difficulty of the original contributor to add support to Oracle, at
>> the same time I also watch again Carlton's keynote at PyCon Italia
>> 2023 because the videos have recently been published. Lastly, while
>> volunteering at the DSF booth at EuroPython 2023, I happened to meet
>> an Oracle Django developer for the first time, who admitted that he
>> had never contributed to the Oracle backend itself.
>>
>> >> Over the last few months, I've tried to encourage newcomers and young
>> users to contribute to Django and they almost always ran into the need to
>> provide compatibility to Oracle, so much so that they eventually gave up
>> contributing.
>> > Really? Django is not only the ORM. It is easy to demonize Oracle. I'm
>> working with contributors on daily basis, and  don't remember anyone who
>> would resign because we have builtin Oracle backend. We don't have much
>> more open tickets in the Oracle backend then in others. The number of
>> unsupported features is similar to SQLite or MySQL.
>>
>> In my personal experience, the people I collaborate with at work or
>> meet in the local communities where I go to talk about Django all have
>> experience with Open Source databases and none have ever worked with
>> Oracle, which makes it very difficult for them to try to contribute in
>> Django's ORM why should they ensure compatibility for this DB without
>> ever having seen it.
>>
>> >> The point is that I think Oracle is a historical anomaly among the
>> database backends supported by Django because it is the only one that is
>> not Open Source, it has irrelevant usage numbers
>> > It's not an anomaly. Oracle support was a conscious decision, keeping
>> the ORM features Oracle-compatible is a good battlefield, that helps
>> keeping the ORM friendly for 3rd-party database backends as we have more
>> feature flags and hooks for custom behaviors.
>>
>> I think this would be the same if the Oracle backend was a third-party
>> package, perhaps maintained by the same company
>>
>> >> ... and the company that earns from it does not contribute in any way
>> to its maintenance or support
>> > Should be also drop support for Windows for exactly the same reason?
>> (rhetorical question)
>>
>> I don't know, I haven't used Windows since 2000 :-)
>>
>> Anyway, tornado to talk about Database, SQL Server is a third-party
>> package
>>
>> >> I, therefore, suggest that we start a discussion on removing Oracle
>> from supported databases.
>> > This was already discusse

Re: Ticket #34646 Ordering a Django admin column based on multiple model fields

2023-06-18 Thread David Sanders
Sorry to clarify I intended to respond with "niche solution" not "nice 
solution" lol. I didn't realise the phone's autocomplete had done that.

On Monday, 19 June 2023 at 11:05:41 UTC+10 David Sanders wrote:

> Mariusz is a developer, so that's at least 1 developer's opinion :)
>
> Unless anybody else pipes up to counter this I'd consider it to be a nice 
> solution.
>
> On Monday, 19 June 2023 at 05:01:52 UTC+10 Mubarak Alrashidi wrote:
>
>> Can we at least know what the developers think about it?
>>
>>
>> On Sunday, June 11, 2023 at 1:28:58 AM UTC+3 Mubarak Alrashidi wrote:
>>
>>> Hello,
>>>
>>> I posted this StackOverflow question 
>>> <https://stackoverflow.com/q/76425892/67579>, and @Willem Van Onsem 
>>> <https://code.djangoproject.com/query?status=!closed&reporter=KommuSoft> 
>>> tried 
>>> to help by opening a ticket numbered #34646 
>>> <https://code.djangoproject.com/ticket/34646>, and creating a patch for 
>>> supporting the order by multiple fields in admin.display decorator.
>>>
>>> But it got closed as a duplicate of #31975 
>>> <https://code.djangoproject.com/ticket/31975> which was reported about 
>>> 3 years ago, and it got closed as wontfix by @Mariusz Felisiak 
>>> <https://github.com/felixxm> because he said: *"We don't want to add 
>>> unnecessary complexity to the API.".*
>>>
>>> And I agree with what @Petr Dlouhý 
>>> <https://code.djangoproject.com/query?status=!closed&reporter=PetrDlouhy>
>>>  says: *"it is small modification of Django code and small increase in 
>>> API complexity (which is consistent with the logic of other order fields, 
>>> BTW)."**.*
>>>
>>> The inconsistency is when somewhere we're able to order by multiple 
>>> fields, and somewhere else we can't.
>>>
>>> If we can order by multiple fields in the modelAdmin classes, why can't 
>>> we do so in the admin.display decorator?
>>>
>>> So, I do hope to reconsider implementing the patch 
>>> <https://code.djangoproject.com/attachment/ticket/34646/django_ordering.py.diff>
>>>  that @Willem Van Onsem 
>>> <https://code.djangoproject.com/query?status=!closed&reporter=KommuSoft>
>>>  created.
>>>
>>> Thanks
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/9de4defb-b14b-4174-8678-4c3b3227aca5n%40googlegroups.com.


Re: Ticket #34646 Ordering a Django admin column based on multiple model fields

2023-06-18 Thread David Sanders
Mariusz is a developer, so that's at least 1 developer's opinion :)

Unless anybody else pipes up to counter this I'd consider it to be a nice 
solution.

On Monday, 19 June 2023 at 05:01:52 UTC+10 Mubarak Alrashidi wrote:

> Can we at least know what the developers think about it?
>
>
> On Sunday, June 11, 2023 at 1:28:58 AM UTC+3 Mubarak Alrashidi wrote:
>
>> Hello,
>>
>> I posted this StackOverflow question 
>> , and @Willem Van Onsem 
>>  
>> tried 
>> to help by opening a ticket numbered #34646 
>> , and creating a patch for 
>> supporting the order by multiple fields in admin.display decorator.
>>
>> But it got closed as a duplicate of #31975 
>>  which was reported about 3 
>> years ago, and it got closed as wontfix by @Mariusz Felisiak 
>>  because he said: *"We don't want to add 
>> unnecessary complexity to the API.".*
>>
>> And I agree with what @Petr Dlouhý 
>> 
>>  says: *"it is small modification of Django code and small increase in 
>> API complexity (which is consistent with the logic of other order fields, 
>> BTW)."**.*
>>
>> The inconsistency is when somewhere we're able to order by multiple 
>> fields, and somewhere else we can't.
>>
>> If we can order by multiple fields in the modelAdmin classes, why can't 
>> we do so in the admin.display decorator?
>>
>> So, I do hope to reconsider implementing the patch 
>> 
>>  that @Willem Van Onsem 
>> 
>>  created.
>>
>> Thanks
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/02535619-27e9-40ec-835b-1ea1c5a08315n%40googlegroups.com.


Re: Oracle 23c released earlier this month

2023-04-21 Thread David Sanders
Looks like python-oracledb is making updates to be compatible with 
23c: 
https://python-oracledb.readthedocs.io/en/latest/release_notes.html#oracledb-1-3-1-tbd

1.3.1 isn't released yet but the fact that updates are being made so soon 
is encouraging 🎉

On Monday, 17 April 2023 at 22:06:57 UTC+10 Mariusz Felisiak wrote:

> Hi,
>
>   Thanks! Also, they finally update VM: 
> https://www.oracle.com/database/technologies/databaseappdev-vm.html 
>   We still have to wait for a compatible driver, cx_Oracle and 
> python-oracledb don't support it yet.
>
> Best,
> Mariusz
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/7fe50d11-4b70-40b5-98b1-6964cd70edb9n%40googlegroups.com.


Re: Django's automatic admin interface.

2023-04-19 Thread David Sanders
Hi Dipankar,

Not being rude but serious question: What's the latest front end
technology? :)

On Wed, 19 Apr 2023, 7:27 pm Dipankar,  wrote:

> Is there any plan to replace Django's automatic admin interface with the
> latest front end technology?
> There are several packages available but what if Django itself provides
> the same as core.
>
> --
> Warm Regards,
> Dipankar B.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAFdBwp_N0remvp8zAPFVda6iyFWVWR%3DZh0EtfE9fzYcPQVixkQ%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-61oX4oh3apDatm_MKCdoYCMLxkk8O4krKMZuPZF2LpNg%40mail.gmail.com.


Oracle 23c released earlier this month

2023-04-17 Thread David Sanders
Hi folks,

For anyone interested Oracle 23c was released earlier this month

.

There are a couple of interesting features but just looking over the
changes it looks like it resolves some caveats that Django has to supply
workarounds for:

   - There's now a BOOLEAN datatype (from the tickets I've worked on this
   is by far the biggest pain point) quoting from the docs: "This enables you
   to store TRUE and FALSE values in tables and use BOOLEAN expressions in SQL
   statements."
   - SELECT now no longer requires a FROM
   - GROUP BY now supports column aliases & position numbers

I realise that we still support older versions of Oracle but perhaps at
least there's some potential for fixing issues that couldn't be resolved
due to the lack of bools if some version detection was put in place?

There may be a few other interesting tidbits related to Django that I've
missed. Here are the updates for application developers:
https://docs.oracle.com/en/database/oracle/oracle-database/23/nfcoa/application-development.html

Cheers,
David

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-7c-ggryJzTE2AT7wy88dNJFWGB0ceW%2Bf2UkwD6N3cJXg%40mail.gmail.com.


Re: Proposal: Check constraints at the model field level

2023-04-16 Thread David Sanders
Hi Adam, Mariusz & Simon,

> The only thing I'm not a fan of in your proposal is repeating the field
name within the check expression, like "price" in
> ... 8< ...
> Perhaps we could support only a special name instead, like “self” or the
shorter “f”?

I was thinking the same thing +1  I wanted to throw up the proposal to
elicit ideas on this because I wasn't sure whether reserving a field name
like this might've been the way to go 🤔


> but it should be noted that SQL has both CHECK on the field and table
level
and from Simon:
> CREATE TABLE / ADD COLUMN checks on the field level are really just
syntactic sugar for checks at the table level

Simon is correct here in that checks at column & table level are both
declarations for the same underlying mechanism (at least from what I've
seen with Postgres & MySQL).


> This proposal is not really nice from a maintenance point of view

Felix if there was no maintenance headache would it sound like a good idea
though? What if there was some way to make it work nicely? I was wondering
what ways that could be achieved:
 - if you use db_check() then there's no migration state conflict; only
potential conflict in the database which would be resolved with unique
constraint naming.
 - as an alternative could it somehow then be syntactic sugar to add to
meta.constraints? this would then have the benefit of automatically being
added to validation. The catch is migrations would need to take the fact
that fields could add to meta into consideration because from what I've
seen it keeps track of the "original" user-defined meta options.


On Fri, 7 Apr 2023 at 04:55, charettes  wrote:

> Small clarification here.
>
> > it should be noted that SQL has both CHECK on the field and table level,
>
> From my understanding CREATE TABLE / ADD COLUMN checks on the field level
> are really just syntactic sugar for checks at the table level like just
> like `REFERENCES` usage is syntactic sugar for foreign key constraints.
>
> > This is not true for unique constraints or indices.
>
> Unique constraints can be defined using the UNIQUE keyword just like CHECK
> is used to define a check per field, it's really just a different way of
> defining that a unique constraint on a field must be created.
>
> The question of whether or not we want to provide some Django syntactic
> sugar in the form of `Field.check` and the benefits it might provide to
> third-parties (and even ourselves for dog fooding PositiveIntegerField)
> remains but I think that it's important to point out that there's no
> distinction between field and table level constraints at the database level
> AFAIK (for Postgres and SQLite at least).
>
> Simon
> Le jeudi 6 avril 2023 à 01:47:48 UTC-4, Adam Johnson a écrit :
>
>> Mariusz, I agree with the burden, but it should be noted that SQL has
>> both CHECK on the field and table level, and CheckConstraint only defines
>> table-level constraints. This is not true for unique constraints or indices.
>>
>> Also, what do you think of a way for custom field classes to add
>> constraints, at least? db_check() is somewhat limiting given it must return
>> raw SQL, plus it's undocumented.
>>
>> On Thu, Apr 6, 2023 at 5:11 AM Mariusz Felisiak 
>> wrote:
>>
>>> Hi,
>>>
>>> This proposal is not really nice from a maintenance point of view as we
>>> will end with the same complicated situation we currently have with
>>> uniqueness checks or indexes i.e. many ways to define the same:
>>>
>>> - Field.unique/index
>>> - Meta.unique_together/index_together
>>> - Meta.constraints/indexes
>>>
>>> It's especially error-prone in migrations and different database
>>> behavior on fields already covered by the same constraints/indexes. I'm
>>> pretty sure that we've introduced Meta.contraints/indexes to avoid this
>>> happening in the future, and we are rather leaning to leave only
>>> Meta.constraints/indexes and remove other options in the future. Not
>>> creating a new one.
>>>
>>> Initial -1 from me.
>>>
>>> Best,
>>> Mariusz
>>>
>>> --
>>>
>> You received this message because you are subscribed to the Google Groups
>>> "Django developers (Contributions to Django itself)" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to django-develop...@googlegroups.com.
>>>
>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/django-developers/954af838-2176-4877-b4ac-70525cddcbf5n%40googlegroups.com
>>> 
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/58ab388c-285

Proposal: Check constraints at the model field level

2023-04-05 Thread David Sanders
Hi folks,

We've had check constraints for a while now and they're awesome.

I'd like to propose an alternative way to declare check constraints: at the
field level. This sounds like it's duplicating the feature but there are
some advantages that make this distinct from declaring at the model-level
from the meta:

   - Colocality: the check rules are close to the field they're concerned
   with
   - Reusability: Allows for bundling with custom field types
   - Good for checks concerned only with the field its declared on, for
   multiple fields recommended to continue to use Meta. (Kind of analogous to
   unique=True vs UniqueConstraint)

For example:

class Product(Model):
price = DecimalField(..., check=Q(price__gte=0))
...
other fields
...


class Meta:
constraints = [
... declare constraints here that are concerned with multiple
fields...
]


For more complex fields you can then bundle the check for reusability:

class PriceField(DecimalField):
def contribute_to_class(self, ...):
super().contribute_to_class(...)
self.check = Q(**{f'{self.name}__gte': 0})


Some other points:

   - To be consistent with model-level check constraints they'd also need
   to participate in validate_constraints().
   - (Small)PositiveIntegerField already has its own implementation of a
   check constraint, enforcing values >- 0 via the private db_check() method.
   I think this is an example of how bundling checks can be useful.
   - I won't go into implementation alternatives but making use of this
   existing db_check() method is one possibility. How participation in
   validation would work would still need to be decided upon.
   - See this Stupid Django Trick
   

   for some experimentation with this idea.


Cheers,
David

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-6Odv0dpo-En3Jm2NqPhBtK7ebaGKBi4OROe1n%2BvHEE-A%40mail.gmail.com.


Re: Issue with get_FOO_display not working in Django admin

2023-04-05 Thread David Sanders
At this point I'll let others chime in with their opinion on whether this
is something that needs to change because:

   1. I rarely use admin
   2. I've never really had the need to override a choice's display over
   those supplied via `choices`

:)

On Wed, 5 Apr 2023 at 19:05, 'Ibrahim Abou Elenein' via Django developers
(Contributions to Django itself)  wrote:

> Isn't this some sort of duplication? why not just use it instead of
> writing its logic again?
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-7r%3D%3Dwybp8XWp7tEdAOYWuhKucXGE_Kjq0twTy%3DN8KWPg%40mail.gmail.com.


Re: Issue with get_FOO_display not working in Django admin

2023-04-04 Thread David Sanders
Hi Ibrahim,

get_FOO_display() isn't intended to be overridden like that, it's just a
convenience method for use in templates/whatever that refers to the
underlying flatchoices.

For clarity, please see the documentation:
https://docs.djangoproject.com/en/4.2/ref/models/instances/#django.db.models.Model.get_FOO_display

Kind regards,
David

On Wed, 5 Apr 2023 at 09:10, 'Ibrahim Abou Elenein' via Django developers
(Contributions to Django itself)  wrote:

> Dear All,
>
> I am writing to report an issue I encountered while working with Django
> admin. I had a model with a field that uses Choices as follows:
>
> ```
> status = FSMField(default=STATUSES.PENDING, choices=STATUSES,
> protected=True)
> ```
> I overrode the get_status_display method, but to my surprise, it did not
> have any effect in the Django admin.
>
> Upon investigating Django's code, I found the following method in
> contrib.admin
>
> ```
> def display_for_field(value, field, empty_value_display):
> from django.contrib.admin.templatetags.admin_list import _boolean_icon
>
> if getattr(field, "flatchoices", None):
> return dict(field.flatchoices).get(value, empty_value_display)
> ```
> I noticed that this method uses flatchoices to get the display value for
> fields with choices. However, it does not take into account any custom
> display methods that may have been defined for the field.
>
> To resolve this issue, I modified the code to use get_FOO_display instead
> of flatchoices as follows:
>
> ```
> def display_for_field(value, field, empty_value_display, model=None):
> from django.contrib.admin.templatetags.admin_list import _boolean_icon
>
> if getattr(field, "flatchoices", None):
> if model:
> return getattr(model, "get_%s_display" % field.name)()
> return dict(field.flatchoices).get(value, empty_value_display)
> ```
> This modification allowed my custom display method to work as expected in
> the Django admin.
>
> However, I am curious to know why Django's code behaves this way and how I
> can make use of this behavior in my application.
>
> Thank you for your attention to this matter.
>
> Sincerely,
> Ibrahim.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/4f432f39-b959-422e-b062-5db54722b18en%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-65tb_3LZq0D%2BVbU4Dh71V%3DGMRWDeFHCuhT8pDcChVn_w%40mail.gmail.com.


Re: GSOC 2023 Discussion and Feedback: Database-level Cascades

2023-03-29 Thread David Sanders
>
> Thank you for your suggestion and nice implementation example. I would try
> to include that approach too.
>

No, that was just an example of a workaround without any of the benefits of
Django's emulation – the presence of a workaround often goes into
determining whether it's worth working on a new feature that isn't trivial
to add.

However, Simon's pointed out an existing pull request that has apparently
done some work to getting db cascades working in tandem with Django. That
sounds like the place where any effort should be put into.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-7siiT8qmZsa0HO7zGEUJh8Yv%3D3EaSWYeb8BdFhz%3DOcSg%40mail.gmail.com.


Re: GSOC 2023 Discussion and Feedback: Database-level Cascades

2023-03-27 Thread David Sanders
Hi Akash,

Database-level cascading deletes is a topic that has been discussed often
since, well probably the dawn of Django 😁  From recollection the main
issue isn't the implementation, it's getting it to play nicely with
Django's cascading emulation.

There are other tickets, but I believe this is the main ticket to refer to:
https://code.djangoproject.com/ticket/21961  There are also plenty of
threads on this group I'm sure you could dig up.

Note that with the introduction of constraints a while back, there's
nothing stopping people from adding their own custom foreign keys that adds
the necessary `ON DELETE` clauses. Here's a demonstration of that:
https://github.com/shangxiao/stupid-django-tricks/tree/master/abusing_constraints#database-level-cascading-deletes

The gist is:

   1. Set your fks to "do nothing" (I haven't tested with other options -
   seems like there could be some conflicts there though)
   2. Define your own fk by extending BaseConstraint and add the necessary
   ON DELETE/ON UPDATE clauses
   3. Add this new fk to your meta's constraints attribute

Check out the tests in that link above for confirmation (only tested on
Postgres).

Anyway, best of luck!
David


On Tue, 28 Mar 2023 at 00:57, Akash Sen  wrote:

> Hello everyone,
> I’ve started this discussion to get feedback for my proposal for the
> project: Database-level Cascades Functionality to Django ORM. I have never
> contributed to any of the official Django projects earlier but I have
> experience using the framework for last 2 years. In this discussion I would
> like to propose a high level view of how this can be implemented, any kind
> of feedback and reference to resources for a more detailed and clear
> perspective about the project from your side would be very much appreciated,
>
> Based on my study it seems quite straightforward and simple to implement.
>
>1. Conduct thorough research and gain an understanding of the existing
>discussions, pull requests, and issues associated with adding support for
>database-level cascading options in the Django web framework.
>2. Specify the requirements for the new feature, including its name
>and behavior, and determine whether it should be a new option
>(on_delete_db) or a modification of the existing one (on_delete).
>3. Develop a ForeignKey subclass that sets a flag indicating that the
>database should manage the cascading options.
>4. Modify the DatabaseSchemaEditor’s add_field() and sql_create_fk()
>methods to recognize the flag and generate SQL accordingly for the specific
>database backend.
>5. Ensure that the implementation performs as intended when tested for
>a single database backend. Then, generalize the implementation so that it
>works for all supported database backends, generating appropriate SQL for
>each.
>6. Integrate the implementation with the Django migrations framework
>to ensure proper handling of database-level cascading options during schema
>migrations.
>7. Write tests to verify that the new feature functions correctly and
>does not interfere with existing functionality.
>8. Submit one or more pull requests containing the changes, and
>collaborate with the Django community to address any feedback or issues
>that may arise.
>
> Here is a link to my proposal : Database-level Cascades Proposal - GSoC
> '23 - Google Docs 5
> 
>
> Due to my beginner level understanding of the codebase there is a lot of
> scope room for improvement. Your suggestions will be of great help.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/bd82a0de-8f0a-47b5-b40d-1672ed05736fn%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-4azV8-50J8-QRpPzXRn2C5OMWHSx1akkg--WUO-c%2BoHA%40mail.gmail.com.


Re: InlineAdmin unable to delete object with read only primary key

2022-11-21 Thread David Sanders
Hi Gagan,

Interesting quirk you've found there, it's possible it could be a bug
though further digging may be required.

A couple of interesting notes I found while fiddling with your example code:

   - If you press "Save and continue editing" there are unspecified form
   errors
   - Setting `editable=False` on the token key fixes these unspecified
   errors and also allows you to delete the token
   - Note that while inline works with `editable=False` it also means that
   you can't create a disabled token because of the nature of how checkboxes
   are handled. This is a separate issue.


David

On Tue, 22 Nov 2022 at 04:42, Gagan Deep 
wrote:

> Hello everyone!
>
> In my project, I have created a model (Token) which uses a custom primary
> key (i.e. it uses a field defined by the model for the primary key instead
> of using "id"). I created an InlineAdmin class for this model and added the
> primary key field to InlineAdmin.readonly_fields. This InlineAdmin is added
> to ModelAdmin.inlines of another model.
>
> After making these changes, it is *not possible* to delete a Token object
> from the InlineAdmin (web interface). After selecting the delete checkbox
> for the Token object and clicking on the "Save and continue" button (of
> ModelAdmin), the page reloads with the Token object still there.
>
> I have created a simple Demo project to replicate this issue,
> https://github.com/pandafy/inline_admin_pk_bug.
>
> I have done some initial debugging, and found that when the primary key is
> added to the InlineAdmin.readonly_fields, an HTML input element for that
> field is not created.
>
> This does not occur when a model has "id" field for the primary key and
> the "id" field is added to InlineAdmin.readonly_fields.
>
> [image: Screenshot from 2022-11-21 23-05-22.png]
>
> I believe this is inconsistent behaviour. I will be more than happy to
> open an issue for this on Trac and work on a potential fix if this is a
> bug.
>
> Regards,
> Gagan Deep
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/85d9b570-d3dc-46ca-8976-8ffcff061c01n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-7OguU6p%2BdSFrRKX_uOOLPpiFSbhPQEvaqnaAQROfoV3Q%40mail.gmail.com.


Re: Switch to a dropdown widget for ListFilter on admin

2022-11-03 Thread David Sanders
Hi Vasanth,

What advantages does a dropdown have over simply placing the options there
though? Typically these sorts of things have horrendous accessibility and
make the code more complex.

--
David

On Fri, 4 Nov 2022 at 02:17, Vasanth Mohan  wrote:

> Hello,
>
> When there are multiple filters on a model, the filter sidebar gets
> cluttered quite rapidly. Is there a specfic reason, we list the options
> over a dropdown?
>
> I'd like to see if there is support to change the default filter widget to
> dropdown? I'd like to reiterate, this merely replaces the list with a
> dropdown, this should not change anything at a functional level. Anything
> complex can continue to use third-party apps.
>
> Thanks
> Vasanth
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/a16ee31b-1f82-47c3-917c-56b8d3b7f892n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-7QTcHfsp0822DbvwpudGPxjY_ehKGvjxKifJ4_KdNUCg%40mail.gmail.com.


Re: Warning in documentation about filtering queryset in ClassBasedViews

2022-10-29 Thread David Sanders
Hi Daniel,

I don't think a warning is necessary here as it's fairly standard Python.

To explain: the timezone.now() is evaluated at module level – ie only once
when the Python module is imported – which explains the behaviour that
you're experiencing.

If you like you can submit a documentation PR with some suggestions but
others may also doubt the value of adding a warning given that the very
next section explains how to do dynamic filtering. Personally I think by
the time you get to advanced Django such as this, Python experience is
assumed :)

Regards,
David

On Sun, 30 Oct 2022 at 00:02, Daniel Gayoso González 
wrote:

> Hello,
>
> Following the example in
> https://docs.djangoproject.com/en/4.1/topics/class-based-views/generic-display/#viewing-subsets-of-objects
> I tried the following
>
> class BookListView(ListView):
> model = Book
> queryset = Book.objects.filter(publication_date__lte=timezone.now())
>
> I found that this code snippet to retrieve only books that has the
> publication date before today (assuming that could be books with
> publication date in the future) not work as I would expected.
>
> After some digging, I found that timezone.now() it's cached when server
> starts up (in a production environment), so this query filter by the date
> the server was started. So the solution is to use a dynamic filtering.
>
> Could be a good idea to include some warning about this in the
> documentation?
>
> Thanks,
> Daniel
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAHLCT5d3Dz3KTfpxhLQAUZjruhRLgb_XKbUKdv7VgHW_-VVfCg%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-59A5U0pLOuZ%2BxdfHp%3Dq%3Ddwgw%2BG_GFaRYQAxfdytX6%2B5Q%40mail.gmail.com.


Re: Proposal: Add An in-memory data storage backend in Django

2022-10-20 Thread David Sanders
Hi,

I may be missing some context here but is this something distinctly
different from setting SQLite to use in-memory storage [1]? 🤔

[1] https://www.sqlite.org/inmemorydb.html

David

On Fri, 21 Oct 2022, 04:30 Paolo Melchiorre (paulox), 
wrote:

> Hi all,
>
> there is a package that provide in-memory data storage backend, but it's
> now abandoned.
>
> Having support for in-memory data storage could be very useful for Django
> itself and furthermore it would involve adding a small code with tests that
> do not justify the creation of a fork of that old package.
>
> We are talking about this during the sprints at DjangoCon US 2023 in San
> Diego with Josh Thomas and Mariusz Felisiak proposed to us to ask here on
> this list.
>
> What do you think about adding an in-memory data storage backend directly
> in the Django core?
>
> Ciao,
> Paolo
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/e0f6d509-20d7-4eef-b570-cc53611dca01n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-64SU%2BdwjKDGmzCZpz06VZ-QUxjb3%2B9RGFp8vqbJSd58Q%40mail.gmail.com.


Re: Proposal to add a flatten() to django.utils

2022-10-18 Thread David Sanders
>
> +1 for that, though this will need some careful design between perf

optimizations and how much general purpose it should be.


Perhaps before optimising we could start out with the basic readable
version and tailor it moving forward. It's possible this could be
irrelevant if it's only ever used alongside heavier operations like
querying a database.

I remember a discussion years ago, whether this should go into python
> batteries. Ended up unresolved, as the optimization goals depend alot on
> the provided data structures. Maybe this can be avoided in django by
> focussing on most typical nested data structures.
>

Interesting… that would explain its absence from itertools. It might be
worth me going back through Python ML to see what was discussed.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-69zb0GGf6ec%3D8255OMiJDs_kzs-%2Bba%3DYGsH0CPx%3D85cQ%40mail.gmail.com.


Proposal to add a flatten() to django.utils

2022-10-16 Thread David Sanders
Hi folks,

As part of PR 16175  there was
some discussion around flattening lists/tuples as part of the solution. I
proposed that if we create a flattening function that there'd be some
benefit in sharing that in django.utils for other components if needed.

I'd like to garner "approval" + any thoughts on the best way to write such
a function.

   - I'm aware that django.db expressions have similar-ish flatten() methods
   - The PR author, Ion Alberdi, has done some nice work in writing up
   alternatives and measuring performance
   - A generator based solution would be nice if it could finish walking
   early if used with any()
   - Opinions on maintainability (readability) vs performance would be great
   - Ideally I think it would be great if someone with some experience with
   performant Python could chime in

Cheers,
David

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-5iwZPtsuw4Z%3D8nP16K%3DnP-0EAD5wZ4WaNy40L5oYuzfw%40mail.gmail.com.


Re: Model-level validation

2022-10-01 Thread David Sanders
I'm not really interested in debating whether the ORM validates or not but
I thought it might be worth pointing out a few things that haven't been
touched on yet:

> It's not right.

Design decisions are often neither outright right nor wrong but more
tradeoffs of varying values.

> The data store layer should protect the validity of the data.

I disagree that the ORM is the data store layer - that's the database. I
never put any guarantees in ORM validation because there's always a myriad
of ways to get around it.

If you want guarantees I suggest you look into setting up constraints,
they're quite easy with Django nowadays. Some examples aside from the usual
unique constraint:

   - Validation of choices? Setup a check constraint to check the value
   exists in the TextChoices `values` attribute.
   - Validation of non-overlapping date ranges? Use range types with
   exclusion constraints.
   - Only 1 column from a set of columns should be set? Use a check
   constraint with an xor not null test.
   - There are plenty more of these :)

Only the database can protect the data.

--
David

On Fri, 30 Sept 2022 at 10:12, Aaron Smith  wrote:

> Why doesn't Django validate Models on save()?
>
> I am aware that full_clean() is called when using ModelForms. But most web
> app development these days, and every django app I've ever worked with, are
> headless APIs. The default behavior is dangerous for the naive developer.
>
> Bringing View-level concepts such as forms or serializers down into celery
> tasks and management commands breaks separation of concerns, and having
> multiple validation implementations at different layers in the app is
> fraught with divergence and unexpected behavior.
>
> It's not right. The data store layer should protect the validity of the
> data.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/37ec0c58-2561-4300-9ead-05160410c389n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-6BoxxsR4q7dUfA7KwgPXc7%3D86nUWdJb8jXPQ_AvVwa4g%40mail.gmail.com.


Re: Proposal: Make it so when getting an image's dimensions, EXIF orientation is considered

2022-09-28 Thread David Sanders
Hi Adam,

Sorry to clarify I was referring to `ImageFile` which has 2 `@property`
attributes `width` and `height` [1].  My suggestion was that you could add
2 additional `@property` attributes that work with EXIF rotation 🙂  (or
something along these lines…)

[1]
https://github.com/django/django/blob/0dd29209091280ccf34e07c9468746c396b7778e/django/core/files/images.py#L18-L24

Regards,
David


On Wed, 28 Sep 2022 at 07:13, 'Adam Johnson' via Django developers
(Contributions to Django itself)  wrote:

> To have extra properties, we'd need to add extra database fields. It would
> be somewhat wasteful to add them to all ImageFields when few users will
> care about the difference.
>
> On Mon, Sep 26, 2022 at 10:28 AM David Sanders <
> shang.xiao.sand...@gmail.com> wrote:
>
>> Actually might as well throw out one idea, feel free to discard:
>>
>> Keep width and height as-is and add 2 additional properties for jpg:
>> `photo_width` and `photo_height` (or named something more suitable)
>>
>> This way it stays inline with other image viewing/editing software which
>> still reports the width and height as is read from the image with the
>> rotation as separate meta-data. (Eg I did a cursory look with Gimp &
>> Preview on mac)
>>
>> On Mon, 26 Sept 2022 at 19:20, David Sanders <
>> shang.xiao.sand...@gmail.com> wrote:
>>
>>> Coincidence I was also just reading up image-orientation… I didn't
>>> realise that it's the default behaviour now to orient.
>>>
>>> I guess it's a question of whether/how to be backwards compatible?
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Django developers (Contributions to Django itself)" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to django-developers+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/django-developers/CADyZw-5mR87oKsDVnyLFwuftxY3As0%3Dz9JXydbSu2-Lvni-F7g%40mail.gmail.com
>> <https://groups.google.com/d/msgid/django-developers/CADyZw-5mR87oKsDVnyLFwuftxY3As0%3Dz9JXydbSu2-Lvni-F7g%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAMyDDM1Lwt0sGLtfb3yY-H_341TiJN-Vd1%2BaFNV6aHvwkZQNkg%40mail.gmail.com
> <https://groups.google.com/d/msgid/django-developers/CAMyDDM1Lwt0sGLtfb3yY-H_341TiJN-Vd1%2BaFNV6aHvwkZQNkg%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-582Q%2BwZ4ouTsjX%2Bq%3DD4xvGb0VsUkTMYRSSZSR_hux2iQ%40mail.gmail.com.


Re: Proposal: Make it so when getting an image's dimensions, EXIF orientation is considered

2022-09-26 Thread David Sanders
Actually might as well throw out one idea, feel free to discard:

Keep width and height as-is and add 2 additional properties for jpg:
`photo_width` and `photo_height` (or named something more suitable)

This way it stays inline with other image viewing/editing software which
still reports the width and height as is read from the image with the
rotation as separate meta-data. (Eg I did a cursory look with Gimp &
Preview on mac)

On Mon, 26 Sept 2022 at 19:20, David Sanders 
wrote:

> Coincidence I was also just reading up image-orientation… I didn't realise
> that it's the default behaviour now to orient.
>
> I guess it's a question of whether/how to be backwards compatible?
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-5mR87oKsDVnyLFwuftxY3As0%3Dz9JXydbSu2-Lvni-F7g%40mail.gmail.com.


Re: Proposal: Make it so when getting an image's dimensions, EXIF orientation is considered

2022-09-26 Thread David Sanders
Coincidence I was also just reading up image-orientation… I didn't realise
that it's the default behaviour now to orient.

I guess it's a question of whether/how to be backwards compatible?

On Mon, 26 Sept 2022 at 19:00, 'Adam Johnson' via Django developers
(Contributions to Django itself)  wrote:

> I’m +1 to making this change. Incorrect orientation is frustrating and
> this is why browsers changed to always consider it (by default).
>
> You're right that the web default is to consider EXIF orientation data,
> controllable with the image-orientation CSS property:
> https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation .
> (FYI, link to MDN in future, it's a more neutral/universal source than
> Chrome docs. MDN shows compat in all browsers, and Chrome implements a lot
> of unique features).
>
> On Sat, Sep 24, 2022 at 5:51 PM Adam Taylor  wrote:
>
>> Following the advice of David Sanders and Mariusz Felisiak, I'm coming
>> here with my proposal rather than continuing on with the ticket system (see 
>> ticket
>> #34035 <https://code.djangoproject.com/ticket/34035>).
>>
>> I understand the reluctance to make this change. However, things change
>> with web browsers and I believe web frameworks should make changes to stay
>> in line with the web browsers. It used to be less common for web browsers
>> to consider EXIF orientation, but now it's the standard. ImageField
>> being able to save the image dimensions to another field is very useful but
>> for my use case it's broken because it doesn't consider EXIF orientation so
>> there are cases where the dimensions are the opposite of what they should
>> be. I highly doubt I'm alone in this. Maybe there should be a setting that
>> can be passed into ImageField to avoid breaking existing projects. I
>> definitely think this should be part of Django rather than having the
>> developers need to add this logic to each of their Django projects that
>> need it.
>>
>> Thoughts?
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Django developers (Contributions to Django itself)" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to django-developers+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/django-developers/c51cfad1-df74-446a-a341-53a007a9ae9fn%40googlegroups.com
>> <https://groups.google.com/d/msgid/django-developers/c51cfad1-df74-446a-a341-53a007a9ae9fn%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAMyDDM1OXhAv%3DvNuha18Ssp0fJFWCfVgDxGK4gYLoKDH%3D5Nqcw%40mail.gmail.com
> <https://groups.google.com/d/msgid/django-developers/CAMyDDM1OXhAv%3DvNuha18Ssp0fJFWCfVgDxGK4gYLoKDH%3D5Nqcw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-6ZxnXf-j%2B7mqnzc2TnzF00ohUO-FehhK9qxnA_7eWuXQ%40mail.gmail.com.


Solutions for ticket #31506

2022-09-24 Thread David Sanders
Hi folks,

Ticket 31506  is an older
ticket that I thought I'd look into – there are a couple of points of
discussion I thought I'd run past folks before offering a PR.

To summarise the issue:

On Postgres when you add or subtract an interval with a date the result is
a timestamp
.
The issue reports that if you have a queryset to calculate an interval,
then using ExpressionWrapper to define the output_field essentially ignores
the response type that the db returns.

Eg:

class StartModel(Model):
start = DateField()

StartModel.objects.create(start=date(2022, 1, 1))
qs = StartModel.objects.annotate(
end=ExpressionWrapper(F("start") + timedelta(days=1),
output_field=DateField())
)
print(type(qs.first().end))


This raises a couple of questions:

*1.* Is this the responsibility of ExpressionWrapper (or the relevant db
backend) to ensure the correct types are returned or is it the
responsibility of the developer to use Cast() ?

The equivalent with Cast() returns the correct type:
qs = StartModel.objects.annotate(end=Cast(F("start") + timedelta(days=1),
output_field=DateField()))
print(type(qs.first().end))


If so, should the ticket be marked as *wontfix*?

*2.* If it is Django's responsibility there are a couple of solutions that
work (fixes failing test attached to the ticket):

*a. Add a db converter:*
diff --git a/django/db/backends/postgresql/operations.py
b/django/db/backends/postgresql/operations.py
index 2303703ebc..e4158b8130 100644
--- a/django/db/backends/postgresql/operations.py
+++ b/django/db/backends/postgresql/operations.py
@@ -1,3 +1,4 @@
+from datetime import datetime
 from psycopg2.extras import Inet

 from django.conf import settings
@@ -354,3 +355,15 @@ class DatabaseOperations(BaseDatabaseOperations):
 update_fields,
 unique_fields,
 )
+
+def get_db_converters(self, expression):
+converters = super().get_db_converters(expression)
+internal_type = expression.output_field.get_internal_type()
+if internal_type == "DateField":
+converters.append(self.convert_datefield_value)
+return converters
+
+def convert_datefield_value(self, value, expression, connection):
+if type(value) == datetime:
+value = value.date()
+return value


*b. Manually cast the expression in ExpressionWrapper*diff --git
a/django/db/models/expressions.py b/django/db/models/expressions.py
index 5e3c7cab82..347c107936 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -1247,6 +1247,10 @@ class ExpressionWrapper(SQLiteNumericMixin,
Expression):
 def as_sql(self, compiler, connection):
 return compiler.compile(self.expression)

+def as_postgresql(self, compiler, connection):
+sql, params = self.as_sql(compiler, connection)
+return "{}::{}".format(sql,
self.output_field.db_type(connection)), params
+
 def __repr__(self):
 return "{}({})".format(self.__class__.__name__, self.expression)

Any other ideas?

Regards,
David

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-5UDjiFBKwL94NiF-pHu3AU82nh-A5Y071q%2BhOiMU0Yig%40mail.gmail.com.


Feature Request: Customisation of constraint error messages in forms

2022-09-19 Thread David Sanders
Hi folks,

Please note this is partly an extension of some discussion in PR 16054 asking
whether single-field unique or check constraints should raise field errors
as opposed to non-field errors
.

As part of Django's new constraint validation, constraints now get a
violation_error_message

to declare custom user-friendly error messages. Currently,
UniqueConstraints with a single field can additionally have form-specific
error messages set via forms' error_messages

dictionary (or in model form fields). If it's decided that check
constraints also raise field errors then they will also be specifically
customisable in forms.

I'd like to propose that constraints raising non-field errors to also be
specifically customisable in addition to the general default set in
violation_error_message – To do this validation errors would need the
`code` kwarg set.

One possibility is setting the code based on the *constraint name*.
Single-field unique constraints already set the code "unique"; and this
works for field errors because there's usually only one unique constraint
defined for a field.

Thoughts?

Cheers,
David

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-7b5JoX1kyQvHPKr9pi_yMSNi3OzsbLtSUOXLC0j7MMvA%40mail.gmail.com.


Re: UniqueConstraint validation error message conditional vs non-conditional

2022-09-12 Thread David Sanders
expected because Django doesn't have a way to express the
>>> constraint in words to present to the user when a condition, which could be
>>> complex, is provided.
>>>
>>> When no conditions are defined the metadata is easy to interpret to form
>>> a sentence out of ("Foo with this field0, field1, fieldN already exists")
>>> while when a condition is provided Q can define very complex criteria that
>>> only the developer is able to express in words. This is the same class of
>>> problem as trying to have a machine describe a text representation of a
>>> regular expression. It's doable for very simple cases but almost impossible
>>> for complex ones.
>>>
>>> We decided not to try to be clever about what the error message should
>>> be and opted to have a default that uses the constraint name when a
>>> condition is present while allowing developers to provide a
>>> `violation_error_message` at constraint initialization to have them express
>>> what a more appropriate error message should be.
>>>
>>> If we take your particular example, how should Django figure out what
>>> the error message should be for a UniqueConstraint of this form?
>>>
>>> UniqueConstraint(
>>> fields=["foo"],
>>> name="unique_uppercase_foo",
>>> condition=Q(test__upper=F("test"))
>>> )
>>>
>>> The developer who defined the constraint is in a much better position to
>>> provide an error that says that "Test with an upper case "foo" must be
>>> unique". If you're not convinced try with a complex condition involving OR
>>> and mixing transform comparison (e.g. a unique constraint only defined on
>>> palindromes)
>>>
>>> Cheers,
>>> Simon
>>>
>>> Le dimanche 11 septembre 2022 à 14:52:47 UTC-4, othnield...@gmail.com a
>>> écrit :
>>>
>>>> nice one there
>>>>
>>>> On Sun, Sep 11, 2022 at 3:36 PM David Sanders 
>>>> wrote:
>>>>
>>>>> Hi folks (and in particular Simon Charette),
>>>>>
>>>>> I had a bit of a gotcha moment when a custom unique constraint
>>>>> validation message disappeared when I added a condition to it. I won't
>>>>> raise a ticket for this because it looks intentional from the constraint
>>>>> validation PR, but I wanted to seek clarification and whether either some
>>>>> adjustment to the behaviour could be made or clarification in the docs.
>>>>>
>>>>> Here's a boiled down example:
>>>>>
>>>>> Validating models with UniqueConstraint usually groups errors by field
>>>>> name:
>>>>>
>>>>> class Test(Model):
>>>>> test = CharField(max_length=255)
>>>>>
>>>>> class Meta:
>>>>> constraints = [
>>>>> UniqueConstraint(fields=["test"], name="unique"),
>>>>> ]
>>>>>
>>>>> Test.objects.create(test="abc")
>>>>> test = Test(test="abc")
>>>>> test.validate_constraints()
>>>>> django.core.exceptions.ValidationError: {'test': ['Test with this Test
>>>>> already exists.']}
>>>>>
>>>>> However if a condition is added to the UniqueConstraint the validation
>>>>> error is categorised as a non-field error:
>>>>>
>>>>> class Test(Model):
>>>>> test = CharField(max_length=255)
>>>>>
>>>>> class Meta:
>>>>> constraints = [
>>>>> UniqueConstraint(fields=["test"], name="unique",
>>>>> condition=~Q(test="")),
>>>>> ]
>>>>>
>>>>> Test.objects.create(test="abc")
>>>>> test = Test(test="abc")
>>>>> test.validate_constraints()
>>>>> django.core.exceptions.ValidationError: {'__all__': ['Constraint
>>>>> “unique” is violated.']}
>>>>>
>>>>> This affects the way custom error messages are defined (eg forms
>>>>> error_messages dict vs constraint violation_error_message)
>>>>>
>>>>> This behaviour is defined in UniqueConstraint.validate() and looks 

Re: UniqueConstraint validation error message conditional vs non-conditional

2022-09-11 Thread David Sanders
Hi Simon,

Cheers for the explanation.

I'm ok with the error message being the "constraint is violated" generic
message as I agree with what you're saying.

Would it be possible to group the message by field in the same way as
standard unique?

ie, would this be an idea?:

django.core.exceptions.ValidationError: {'test': ['Constraint “unique” is
violated.']}

This way the customised error message would be preserved.

This also leads to another question I had about whether it might be an idea
to allow overriding error messages for constraints in forms using the
error_messages dict… but I'll leave that for another post :)

Regards,
David

On Mon, 12 Sept 2022 at 11:53, charettes  wrote:

> Hello David,
>
> This is expected because Django doesn't have a way to express the
> constraint in words to present to the user when a condition, which could be
> complex, is provided.
>
> When no conditions are defined the metadata is easy to interpret to form a
> sentence out of ("Foo with this field0, field1, fieldN already exists")
> while when a condition is provided Q can define very complex criteria that
> only the developer is able to express in words. This is the same class of
> problem as trying to have a machine describe a text representation of a
> regular expression. It's doable for very simple cases but almost impossible
> for complex ones.
>
> We decided not to try to be clever about what the error message should be
> and opted to have a default that uses the constraint name when a condition
> is present while allowing developers to provide a `violation_error_message`
> at constraint initialization to have them express what a more appropriate
> error message should be.
>
> If we take your particular example, how should Django figure out what the
> error message should be for a UniqueConstraint of this form?
>
> UniqueConstraint(
> fields=["foo"],
> name="unique_uppercase_foo",
> condition=Q(test__upper=F("test"))
> )
>
> The developer who defined the constraint is in a much better position to
> provide an error that says that "Test with an upper case "foo" must be
> unique". If you're not convinced try with a complex condition involving OR
> and mixing transform comparison (e.g. a unique constraint only defined on
> palindromes)
>
> Cheers,
> Simon
>
> Le dimanche 11 septembre 2022 à 14:52:47 UTC-4, othnield...@gmail.com a
> écrit :
>
>> nice one there
>>
>> On Sun, Sep 11, 2022 at 3:36 PM David Sanders 
>> wrote:
>>
>>> Hi folks (and in particular Simon Charette),
>>>
>>> I had a bit of a gotcha moment when a custom unique constraint
>>> validation message disappeared when I added a condition to it. I won't
>>> raise a ticket for this because it looks intentional from the constraint
>>> validation PR, but I wanted to seek clarification and whether either some
>>> adjustment to the behaviour could be made or clarification in the docs.
>>>
>>> Here's a boiled down example:
>>>
>>> Validating models with UniqueConstraint usually groups errors by field
>>> name:
>>>
>>> class Test(Model):
>>> test = CharField(max_length=255)
>>>
>>> class Meta:
>>> constraints = [
>>> UniqueConstraint(fields=["test"], name="unique"),
>>> ]
>>>
>>> Test.objects.create(test="abc")
>>> test = Test(test="abc")
>>> test.validate_constraints()
>>> django.core.exceptions.ValidationError: {'test': ['Test with this Test
>>> already exists.']}
>>>
>>> However if a condition is added to the UniqueConstraint the validation
>>> error is categorised as a non-field error:
>>>
>>> class Test(Model):
>>> test = CharField(max_length=255)
>>>
>>> class Meta:
>>> constraints = [
>>> UniqueConstraint(fields=["test"], name="unique",
>>> condition=~Q(test="")),
>>> ]
>>>
>>> Test.objects.create(test="abc")
>>> test = Test(test="abc")
>>> test.validate_constraints()
>>> django.core.exceptions.ValidationError: {'__all__': ['Constraint
>>> “unique” is violated.']}
>>>
>>> This affects the way custom error messages are defined (eg forms
>>> error_messages dict vs constraint violation_error_message)
>>>
>>> This behaviour is def

UniqueConstraint validation error message conditional vs non-conditional

2022-09-11 Thread David Sanders
Hi folks (and in particular Simon Charette),

I had a bit of a gotcha moment when a custom unique constraint validation
message disappeared when I added a condition to it. I won't raise a ticket
for this because it looks intentional from the constraint validation PR,
but I wanted to seek clarification and whether either some adjustment to
the behaviour could be made or clarification in the docs.

Here's a boiled down example:

Validating models with UniqueConstraint usually groups errors by field name:

class Test(Model):
test = CharField(max_length=255)

class Meta:
constraints = [
UniqueConstraint(fields=["test"], name="unique"),
]

Test.objects.create(test="abc")
test = Test(test="abc")
test.validate_constraints()
django.core.exceptions.ValidationError: {'test': ['Test with this Test
already exists.']}

However if a condition is added to the UniqueConstraint the validation
error is categorised as a non-field error:

class Test(Model):
test = CharField(max_length=255)

class Meta:
constraints = [
UniqueConstraint(fields=["test"], name="unique",
condition=~Q(test="")),
]

Test.objects.create(test="abc")
test = Test(test="abc")
test.validate_constraints()
django.core.exceptions.ValidationError: {'__all__': ['Constraint “unique”
is violated.']}

This affects the way custom error messages are defined (eg forms
error_messages dict vs constraint violation_error_message)

This behaviour is defined in UniqueConstraint.validate() and looks to be
intentional from this advice from Simon:
https://github.com/django/django/pull/14625#issuecomment-897275721

I was wondering what the rationale for that was? Would it be possible to
make the behaviour consistent? And if not - would a PR to clarify how
ValidationErrors are raised for constraints in the docs be welcomed?

Cheers,
David

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-5w94wvx26OVdSaDHGjKxRGvdnCZYeMOM-p4J9t9JUqMw%40mail.gmail.com.


Re: Django timing

2022-09-09 Thread David Sanders
Hi Pelumi,

It's kind of you to offer code, however there is a similar functionality in
contrib.humanize:
https://docs.djangoproject.com/en/4.1/ref/contrib/humanize/#naturaltime

Perhaps this does what you require?

--
David

On Fri, 9 Sept 2022 at 23:50, Bhuvnesh Sharma  wrote:

> Hi,
> if you are using templates then you can simply write:
>
> {{message.created|timesince}} ago
>
> where created is a field of message storing the date and time when the
> message was created.
>
> created =  models.DateTimeField(auto_now_add=True)
>
>
> On Friday, September 9, 2022 at 7:11:00 PM UTC+5:30 pmicha...@gmail.com
> wrote:
>
>> Hello. I was developing an instagram clone website but got a problem when
>> I wanted to add timing to the post, timing like "2 minutes ago", "just now"
>> etc. I searched through the internet I couldn't get the right solution (I
>> don't know if there is solution for it yet). Then I decided to go on a
>> journey of solving the problem myself, which I did and I will like to share
>> the codes with the community for review and improvements (if any). I have
>> no idea where to do that, I will love to get a reply soon because I cannot
>> wait to contribute to django. I am also ready to give full detail of the
>> code and how to use.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/664a2283-be6d-49db-9316-7940b013297fn%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-7Vq%3DMoJhWVtMsrCD99a%3D_82P4xrT3xqQx6PzF8rqYSMA%40mail.gmail.com.


Check constraint validation with NULLs

2022-09-08 Thread David Sanders
Hi folks,

I've noticed a difference in the way check constraint validation behaves
compared to the way Postgres (assuming similar behaviour in other DBs)
validates when dealing with NULLs.

Given a model with a simple positive check constraint:

class Test(Model):
test = IntegerField(null=True)

class Meta:
constraints = [
   CheckConstraint(check=Q(test__gte=0), name="positive"),
]

Then the an instance with a NULL will save but fail validation:

test = Test()
test.save()
test.validate_constraints()
...
E   django.core.exceptions.ValidationError: {'__all__':
['Constraint “positive” is violated.']}


I believe this is due to the way validation is handled in the WHERE
clause. I've
trawled back through the PR discussion and original ticket as well as the
validation code – I could see the original comment about moving validation
to WHERE to get around issues with using SELECT but couldn't find any other
mention about how NULLs should be handled.

I wanted to check with folks here first before raising an issue. I'm not
sure what the fix should be but I'd recommend at least adding a note in the
docs if it's not fixable? :)

Cheers,
David

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CADyZw-4uYZnpWgjOXT-Wa2BSs%2BG1f4PNFD0YDU096bK9Uzc0tw%40mail.gmail.com.


Re: Feature Request (have sample implemenation): ALL subquery

2022-08-24 Thread David Sanders
I'm no expert on how PG optimises queries but NOT EXISTS appears to produce 
the desired execution plan.

My original rationale was to improve the readability and "solution 
accessibility" for lack of a better term. This all came about because a 
colleague couldn't figure out how to do it as a Django query so resorted to 
app-level rigmarole & multiple queries (our use case involved multiple 
many-to-many's). I showed them the ~Exists() approach then the All() 
approach and they picked All() because of the natural readability 🤷‍♂️.

This is just something I quickly whipped up (ignore the execution time when 
I ran them through pgbench they were roughly the same on average):

# update pgbench_accounts set abalance = 10 where bid in (4, 7);
UPDATE 20

# explain analyze SELECT * FROM pgbench_branches b WHERE 't' = ALL (SELECT 
abalance > 0 FROM pgbench_accounts a WHERE b.bid = a.bid );
 QUERY PLAN

 Seq Scan on pgbench_branches b  (cost=0.00..163366.10 rows=5 width=364) 
(actual time=486.614..602.467 rows=2 loops=1)
   Filter: (SubPlan 1)
   Rows Removed by Filter: 8
   SubPlan 1
 ->  Seq Scan on pgbench_accounts a  (cost=0.00..32423.00 rows=10 
width=1) (actual time=46.929..58.739 rows=20001 loops=10)
   Filter: (b.bid = bid)
   Rows Removed by Filter: 430258
 Planning Time: 0.360 ms
 Execution Time: 602.516 ms
(9 rows)

# explain analyze SELECT * FROM pgbench_branches b WHERE NOT EXISTS (SELECT 
1 FROM pgbench_accounts a WHERE b.bid = a.bid and abalance = 0);
QUERY PLAN
--
 Nested Loop Anti Join  (cost=0.00..32183.84 rows=1 width=364) (actual 
time=753.089..951.244 rows=2 loops=1)
   Join Filter: (b.bid = a.bid)
   Rows Removed by Join Filter: 3702576
   ->  Seq Scan on pgbench_branches b  (cost=0.00..1.10 rows=10 width=364) 
(actual time=0.008..0.013 rows=10 loops=1)
   ->  Seq Scan on pgbench_accounts a  (cost=0.00..32173.00 rows=799867 
width=4) (actual time=0.002..68.581 rows=370258 loops=10)
 Filter: (abalance = 0)
 Rows Removed by Filter: 8
 Planning Time: 0.206 ms
 Execution Time: 951.263 ms
(9 rows)


On Thursday, 25 August 2022 at 00:41:43 UTC+10 charettes wrote:

> Hello David,
>
> Do you know if ALL provides any performance benefits over NOT EXISTS? 
> Given we already support
>
> Employee.objects.filter(
> ~Exists(Employee.objects.filter(
>  manager=OuterRef("pk"),
>  join_date__gt=OuterRef("join_date")
>  )
> )
>
> If it's not the case I'm not sure adding support for ALL to core is worth 
> it, particularly because we need to emulate it on SQLite.
>
> If we were to add it I think All(lookup, subquery) would make the most 
> sense as it still looks a bit like how you'd do things In Python and it's 
> relatively easy to translate to NOT EXISTS as you basically take the lookup 
> and the selected value and turn it into 
> ~Exists(subquery.exclude(Lookup(OuterRef(field, value))).
>
> Employee.objects.filter(
> All(
>"join_date__lte", Employee.objects.filter(
>manager=OuterRef("pk")
>).values("join_date")
> )
> )
>
> Generally I'm +0 on the idea though unless we can prove there are use 
> cases for it that Exists can't solve.
>
> Cheers,
> Simon
>
> Le mercredi 24 août 2022 à 09:53:46 UTC-4, shang.xia...@gmail.com a 
> écrit :
>
>> Hi folks!
>>
>> I have a piece of low hanging fruit I'd like to suggest and contribute: 
>> ALL subqueries.
>>
>> Here's the PG docs on ALL subqueries 
>> 
>>  
>> but basically it causes the subquery expression to evaluate to true only if 
>> all rows themselves evaluate to true when compared against the supplied 
>> value & comparison operator.
>>
>> The syntax is:
>>
>>   ALL ()
>>
>> I've played around with this idea in my "Stupid Django Tricks" repo 
>> 
>>  
>> and have taken the liberty of also creating a small patch for Django 
>> 
>> .
>>
>> There are a couple of points to note:
>>
>> 1. Postgres, MySQL & SQL Server all support ALL subquerying *but 
>> unfortunately SQLite does not*. A cursory search about Oracle suggests 
>> it may support it but couldn't see anything in the official docs.
>>
>> 2. An equivalent expression is to use NOT EXISTS and move the comparison 
>> logic into the subquery & invert it (but leaving any correlating logic 
>> uninverted).
>>
>> A couple of further points on the NOT EXISTS approach:
>>
>>1. It uses 

Feature Request (have sample implemenation): ALL subquery

2022-08-24 Thread David Sanders
Hi folks!

I have a piece of low hanging fruit I'd like to suggest and contribute: ALL 
subqueries.

Here's the PG docs on ALL subqueries 

 
but basically it causes the subquery expression to evaluate to true only if 
all rows themselves evaluate to true when compared against the supplied 
value & comparison operator.

The syntax is:

  ALL ()

I've played around with this idea in my "Stupid Django Tricks" repo 
 
and have taken the liberty of also creating a small patch for Django 

.

There are a couple of points to note:

1. Postgres, MySQL & SQL Server all support ALL subquerying *but 
unfortunately SQLite does not*. A cursory search about Oracle suggests it 
may support it but couldn't see anything in the official docs.

2. An equivalent expression is to use NOT EXISTS and move the comparison 
logic into the subquery & invert it (but leaving any correlating logic 
uninverted).

A couple of further points on the NOT EXISTS approach:

   1. It uses double negatives and hinders the readability.
   2. It's not always obvious what the correct way to invert the subquery 
   is – I found I had to be careful with filters involving many relationship 
   lookups.


That being said I found that getting ALL working in Django only took a few 
lines. From my initial experimentation I saw 3 possible ways of doing this:

1. Lookups: A lookup could be defined for each operator supported.

eg using Exact:

class All(Exact):
lookup_name = "all"
def get_rhs_op(self, connection, rhs):
return connection.operators[super().lookup_name] % f"ALL {rhs}"

Parent.objects.annotate(test=Value("test")).filter(test__all=Subquery(subquery))

2. Subclass Subquery

This is my favoured approach as it resembles Python's all() builtin. It 
uses almost identical code to Exists except for one line that defines the 
exists expression. The idea is that subqueries supply a single boolean 
column created with annotate:

class All(Subquery):
template = "'t' = ALL (%(subquery)s)"
output_field = fields.BooleanField()
# similar methods to Exists omitted

Parent.objects.filter(
All(
Child.objects.annotate(is_result=Q()).filter(something=OuterRef('something').values('is_result')
)
)

2. Translate the expression to NOT EXISTS.

I'm not entirely sure what the best approach is for this, or even whether 
it's possible, but it would need to negate the subquery filtering while 
leaving the correlating filter (ie the OuterRef) alone.

My naive attempt here works for the simplest of cases but doesn't take into 
account anything more complex. 



I found this work well for my codebase and I'd love to explore contributing 
it back to Django. I'd suggest the subquery subclass as it results in more 
readable code – but there is the question about lack of support for SQLite. 
One approach would be to note in the documentation on how to write the 
equivalent using NOT EXISTS.

What do folks think?

Cheers,
David



-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/13780399-0b14-48de-86d1-24a530199c5dn%40googlegroups.com.


Re: More eyes on Check Constraints

2017-08-13 Thread David Sanders
Hi Ian,

Interestingly enough I'd just recently 
written https://github.com/rapilabs/django-db-constraints based on Matt 
Schinckel's idea.  I wrote that because although check constraints are 
great, I really wanted a way to supply any type of constraint - primarily 
composite foreign keys.  I don't suppose that this would be a possibility 
as a future extension of your pull request?

Cheers,
David


On Friday, August 11, 2017 at 4:15:26 AM UTC+10, Ian Foote wrote:
>
> Hi all, 
>
> I've been working on https://code.djangoproject.com/ticket/11964 to add 
> support for Check Constraints to the Django ORM and migrations 
> framework. My work can be found at 
> https://github.com/django/django/pull/7615. 
>
> I think the functionality is basically there, so what it really needs is 
> some testing on real-world use-cases and more eyes to suggest any 
> further simplifications or improvements that may be possible. 
>
> Thanks, 
>
> Ian 
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/537b284f-400c-45c9-8f3b-91842c83f6d8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Admin Themes in 1.10

2016-05-08 Thread David Sanders
Ever since PR #5567 [1] (which is great, yay CSP) I've been concerned about
the impact it will invariably have on admin themes going forward. By
removing any inline JS, the various admin JS functionality is now
initialized in the JS files where it is much harder to extend or change for
an admin theme. None of the niceties of template blocks and extending
templates exist with the JS files, the only way to extend those would be to
duplicate the entire file, which is a non-starter from a maintenance
perspective. This cuts off the nice options added to these JS files since
themes can no longer effect these options.

Possible ways to resolve this include:
  * Move all JS initialization code to a single file which can be
overridden by an admin theme (still requires duplicating all of the
initialization code)
  * Add an optional attribute to the relevant HTML which prevents the
initialization code from running, allowing themes to manually run
initialization code with custom options

I'm a fan of the second option because it allows the most flexibility. An
admin theme can use custom options without duplicating much code, and a
custom TabularInline subclass can be created and use a custom template and
JS to provide custom options specific to that inline class.

I've added a patch [2] which adds this functionality to the two admin
jQuery plugins which are most likely to be initialized with alternate
options: actions.js and inlines.js. For the former the attribute goes on
the div.actions and for the latter it goes on the
div.js-inline-admin-formset. I used the attribute
'data-disable-document-ready', but the name could just as easily be
'data-disable-auto-initialize' or something shorter if there's distaste for
the long names.

Thoughts? I'd like to restore this ability to easily provide different
options to these admin jQuery plugins before 1.10 is finalized as it will
be harder to put the cat back in the bag if it ships without the ability.

- David

[1] https://github.com/django/django/pull/5567
[2] http://pastebin.com/wcCk8T3n

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAEXbqgwUdzG_WuTC-2h7cCuGReFY-j3GsQN%2B-RxuKBZ_pTWLWQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Help Text Per Model Field Choice

2016-05-08 Thread David Sanders
Hey all,

I think it would be a greatly useful feature to be able to set help text
for choices on a model field.

For the default Select widget this would be rendered as the title attribute
for each choice, which browsers show when you hover over a choice. This
also makes it simple to render the help text nicely using Select2, here's a
quick example JSFiddle: https://jsfiddle.net/tt1a9zk6/

Beyond Select, for rendering radio buttons it looks like title is also
shown on hover by browsers, but it's a little less intuitive because you
need to hover over the radio button, or put the title on the label instead.
In admin, adding a little '?' icon like the one for the field help text on
tabular inlines would would be a slick way to do it for radio buttons.

Since the pattern for model field choices being a tuple is pretty ingrained
and changing the plumbing to allow for an optional third value (the help
text) would require a lot of change, I opted for using a tuple subclass to
tack on the extra help text information. From the user perspective they'd
still be providing tuples for the choices, with an optional third value.

class FooBar(models.Model):
STATUS_UNKNOWN = 0
STATUS_SNAFU = 1
STATUS_FUBAR = 2

STATUSES = (
(STATUS_UNKNOWN, _("Unknown")),
(STATUS_SNAFU, _("SNAFU"), _("Situation Normal: All Fouled Up")),
(STATUS_FUBAR, _("FUBAR"), _("Fouled Up Beyond All Recognition"))
)

status = models.IntegerField(choices=STATUSES, help_text=_("What's the
current status?"))

Under the covers the tuple gets converted to an instance of the class,
which I called ChoiceTuple in my proof of concept patch (found at the end
of this message). The help text gets set as an attribute on the instance so
that it can be retrieved by aware widgets. If a widget isn't aware of the
ChoiceTuple class, the choice acts like a two value tuple like it currently
is. The only tricky bit is unwinding the choices value when it's broken
into named groups, or is a callable, the code there is iffy, but it was
just to get the proof of concept working.

The nice thing about this approach is it also works nicely with
ModelChoiceIterator, making it quick and easy to grab help text for choices
populated from models in the DB off of one of the fields. This is useful
for situations where the choices are a curated list in the database. The
proof of concept patch tries to get the help text from a field on the model
named help_text if present. That code wouldn't be included in the final
patch, it's just an example.

Thoughts? The addition of the class ChoiceTuple nicely minimizes the amount
of changes needed to plumb the change all the way from the model field to
the widget. I'm not married to the approach, I'm just looking for a clean
way to allow help texts per choice.

Proof of concept patch (based on current master):
http://pastebin.com/90g6mUQ8

- David

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAEXbqgzhMj8kASksnO9nwFqJoNeMChV0X6ACuX8_OpOoX%3D0atg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.