Re: Deprecate CICharField, CIEmailField, CITextField

2023-09-06 Thread 'Johannes Maron' via Django developers (Contributions to Django itself)
Hi again,

We started creating a 3rd party django-citext package, to ensure future
support of PotsgreSQL's CITEXT extension under a corporate funding.
You can find the project here: https://github.com/voiio/django-citext

While doing so, I noticed a couple of small things, where I'd love some
clarification to know which way to go:

   1. Will the CITextExtension stay? It's currently not deprecated, it's
   super class implements array support.
   2. The documentation currently can be misleading. Would you consider
   proposals for some changes:
  - There is a note about performance considerations, yet I couldn't
  find any. There are some limitations, which rightfully need to be
  considered when using the citext extension.
  - The deprecation hint towards collations. However, as previously
  explained, they are by no means an equal replacement. Would you accept a
  reference to a named or unnamed 3rd party solution for future support of
  the citext extension.
   3. Finally, Django's admin or rather lookups, don't play particularly
   nice with collations. Something to consider in the deprecation process.


I am happy to get some feedback, especially on the extension and array
support, since we haven't implemented that yet.
If you have any other pointers, feel free to leave an issue report.

Thanks!
Joe


On Fri, May 12, 2023 at 5:19 PM Johannes Maron 
wrote:

> Hi,
>
> Yes, I hope Django will continue to expand expression support. I worked so
> hard on the SQL compiler to facilitate those kinds of features.
> Anyhow, since db collations are not an adequate replacement for CI text,
> we will create an open-source backport of the CITEXT fields.
> Once we are done, I will open a PR to alter the documentation, to point
> towards this option. This should allow users to choose, and will probably
> easy migration to Django 5 for some.
>
> But first, I gotta play Tears of the Kindom….
>
> Cheers!
> Joe
>
>
> On Fri, May 12, 2023 at 1:37 PM 'Adam Johnson' via Django developers
> (Contributions to Django itself) 
> wrote:
>
>>
>> What I am struggling now with is whenever I specify
>>> `db_collation="case_insensitive"` on the field and this field is used in
>>> `ModelAdmin.search_fields` - Django simply breaks (as it by default uses
>>> `icontains` lookup).
>>> That is quite unfortunate for the big projects, as I have to come up
>>> with some generic solution to something that was not broken before this
>>> feature deprecation (and the docs does not mention this case).
>>> Good that Adam covered it in the article, but I feel that this could be
>>> handled on a lower level than right now. Currently, we'd need to write a
>>> manual annotation for admin queryset in almost every project that uses
>>> usernames or emails (which my guess is something you'd want to be
>>> case-insensitive on a database level).
>>>
>>
>> Yes, I discovered this too. It's what prompted me to write the
>> parametrized admin tests covered in my later blog post:
>> https://adamj.eu/tech/2023/03/17/django-parameterized-tests-model-admin-classes/
>>
>> Annotating appropriately is what I found to work.
>>
>> Tom Carrick wrote earlier:
>>
>> I actually think the best practice right now for having searchable
>>> case-insensitive emails is to do it old-school - have a regular EmailField
>>> with an index on UPPER("email") and then make sure you always use iexact,
>>> istartswith etc. and this will properly use the indexes and result in a
>>> faster search.
>>>
>>
>> I also think this may be a better approach, now. But I haven't tried it.
>>
>> Django 5.0 will hopefully come with generated fields:
>> https://github.com/django/django/pull/16417 . We may then be able to
>> store the user-provided email in "email_original_cased" (or whatever) and
>> make "email" a GeneratedField(expression=Lower("email")), with the
>> lowercase collation and a unique consrtaint. We'll have to see...
>>
>>
>>> For example, in terms of documentation, we could add a note on
>>> `db_collation` to `icontains` page:
>>> https://docs.djangoproject.com/en/4.2/ref/models/querysets/#icontains
>>
>>
>> That sounds like too specific a note to add. Many different data types in
>> many different databases fail to work with some existing lookups, such as
>> several custom fields in Django-MySQL:
>> https://django-mysql.readthedocs.io/en/latest/model_fields/index.html
>>
>>
>> On Sat, May 6, 2023 at 9:50 AM 'Johannes Maron' via Django developers
>> (Contributions to Django itself) 
>> wrote:
>>
>>> Hello again,
>>>
>>> I trust Mariusz' assessment regarding the maintainability. In that case,
>>> I presume a separate package from a 3rd party with commercial interest
>>> might be the best option going forward.
>>>
>>> Thanks for all the considerations and explanations.
>>>
>>> Cheers!
>>> Joe
>>>
>>> On Wed, Apr 19, 2023 at 3:48 PM fly.a...@gmail.com <
>>> fly.amur...@gmail.com> wrote:
>>>
 Hey everyone!

 Thanks for the discussion.
 And special 

Re: Allow applications to register links in the admin interface

2023-09-06 Thread Shlomo
You have some great points that I definitely overlooked in the initial 
implementation. I don't think that overloading the template is a great 
solution since there are still some features that registered links will add 
that cannot be done with a simple template override.

   -  It is easier to selectively show links to users based on the request 
   or a custom permission in a method rather than in the template.
   - Currently each app would have to override the navbar userlinks section 
   completely and add their relevant links which would not work if another 
   third party app also overrides the same section. Unless {{ block.super }} 
   is used. {{ block.super }} is not a great option since it would limit links 
   to be added to only the beginning of the block (before VIEW SITE) or the 
   end (after the color theme toggle). It is also close to impossible to set 
   the ordering of links when using the {{ block.super }} approach. 
   - No Django apps will add a quick links section to the admin and expect 
   other apps to use that apps Quick Links section. If the Quick Links section 
   is implemented many different apps can utilize this central location to put 
   links. (a setting can be added to disable this)
   - If the app is not sure if the user wants the admin to have the link 
   the app can have the link class available and let the user register it.

The implementation can be changed to use a class-based approach. This will 
work similar to how the ModelAdmin class works. The target attribute and 
onClick can be set in the new AdminLink class. For users who need even more 
control it can have a method .to_html() with can be overridden to display 
the final html link element. To decide if a link should be shown to a 
specific user there can be another method called .will_display that will 
except a request object and will return True or False if that user can see 
the link or not.
This can even use the Django permissions framework by default to determine 
if the user should see the link or not. Similar to how the 
PermissionRequiredMixin works.
You will still be able to override the template if needed the same way as 
before.
I definitely hear that having modifiers using strings can be error prone 
and won't scale well but this can be changed to use ENUMS instead.

The user will be able to override any of these methods to customize how the 
links are displayed.

class RegisterDjango(admin.UrlAdmin):
menu_order = 5
on_click = None
permission_required = ["polls.view_choice", "polls.change_choice"]
url = "https://djangoproject.com";
name = "Django"
target = "_blank"
location = admin.Location.QUICK_LINKS

def get_location(self, request):
return self.location

def get_menu_order(self,request):
return self.menu_order

def get_on_click(self,request):
return self.on_click

def will_display(self,request):
if request.user.has_perms(self.permission_required):
return True
return False

def get_url(self,request):
return self.url

def get_target(self, request):
return self.target

def get_name(self, request):
return self.name

def to_html(self,request):
return f'{
self.get_name(request)}'


admin.site.register_url(RegisterDjango)

Most apps will likely add additional links to the Quick Links section, so 
they won't need to be wrapped. This will also cause the navbar not to have 
so many links. If needed there can be a max links setting that can limit 
the number of additional links in the navbar.

As far as link ordering I think that using an approach similar to wagtail 

 would 
be the best option. In the class add a menu_order which will take a number 
1 to 999. The lower the number the earlier in the list it will show up.

Please let me know what you think about this.
On Wednesday, September 6, 2023 at 8:56:54 AM UTC-4 natali...@gmail.com 
wrote:

> I agree with Adam's assessment. When first reading the proposal, my first 
> thought was that having modifiers such as `location="navbar"` would not 
> scale well. On the one hand, matching against strings could be error prone, 
> and on the other hand, the list of options for a valid location could start 
> getting messy, not to mention if later we also need to add CSS class names 
> or similar the call. Then, it could also get messy with multiple 
> applications registering many links. How are the links sorted? How are they 
> "wrapped" if they are too many? What about duplicate links?
>
> Adding to the above, there are many examples published in online tutorials 
> and related sites that show how to do this links customization if needed, 
> so I think we should not add this to the Django admin.
>
> Natalia.
>
>
> On Tuesday, September 5, 2023 at 5:31:09 AM UTC-3 Adam Johnson wrote:
>
> I think there’s no need to add a feature her