Re: dynamically added INSTALLED_APPS

2023-02-23 Thread Christian González


Am 22.02.23 um 22:37 schrieb Jörg Breitbart:



Am 21.02.23 um 22:05 schrieb Christian González:
My original question was HOW would I implement this in a 
"good-practice" way, by not violating Django's conventions, and 
showing a way it could be done clean.


I think thats not really feasible without big restrictions on the apps 
and what they might bring into a running django instance. Main reason 
being the multistage bootstrapping with collecting phases, esp. on ORM 
side. While it is possible to create models on the fly, they will not 
fully integrate properly. You'd have shim in all the bookkeeping, 
cache abstractions and static globals (django still has a few of 
those) and alter their values in way, that would resemble a clean 
startup. And with multithreading things will get really funny here.


Hm - maybe I don't understand this (& Django bootstrap process) in 
depth, or I didn't make myself clear enough...


I don't want to interfer with Djangos setup process in various ways. 
What you say would be true if GDAPS would try to hook into many 
processes Django does at the start.


I just add some strings to INSTALLED_APPS at the time of parsing 
settings.py. In fact, there is:


   INSTALLED_APPS = [
    "django.contrib..."
    "..."
    "myapp.core"
   ]

   PluginManager.find_apps(INSTALLED_APPS, "myapp.plugins")

Here, PluginManager has a method that receives the INSTALLED_APPS, loads 
all plugins' main modules, extracts their INSTALLED_APPS list, and 
merges them into the main.
So after this line, INSTALLED_APPS contains additionally e.g. 
"myapp.plugins.foo_plugin" and "djmoney".


If you introduce on-the-fly app loading, demand for on-the-fly app 
unloading or app updating is around the corner. Thats like opening 
pandora's box (from dangling refs to not gc'ing/freeing at all due to 
some deeply held ref).


Overall I think any attempt into these on-the-fly directions will lead 
to serious stability issues.



I don't want to introduce on-the-fly-anything... This would, as you say 
correctly, interfere with Django's internals and eat your dog, or worse. 
Never wanted to do that. After that line (code above), everything goes 
the normal Django way of loading.


Of course, to add or remove a plugin, you have to restart the server, 
and run migrate etc mgmt commands, as I said earlier.



And it **works** perfectly this way, I use it (even unofficially in 
production) on a daily base. I just want to know if there is a better 
approach than placing an INSTALLED_APPS list (or a method) into the 
**main module** of a plugin...



Cheers,

Christian



Cheers,
Jörg


--
Dr. Christian González
https://nerdocs.at

--
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/23d61d8c-9d4d-23fc-ff30-5e04a885755a%40nerdocs.at.


Need help for my first Open Source Contribution.

2023-02-23 Thread Siddhiraj R Kolwankar
Helllo Everyone!
Im Siddhiraj R Kolwankar.
Currently I'm pursuing BE in Artificial Intelligence and Data Science from 
Terna Engineering College.
I have more than 2 years of experience in Backend Development. ( 
Python/Django ).
Im interested in Open Source Contribution but I don't know anything about 
it. How to start and what things to follow and I want to contribute as a 
developer. Can anyone help me for my first Open Source Contribution...?

Thank you!

Linktree: https://linktr.ee/siddhirajkolwankar

-- 
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/6b860142-4fe2-4140-bb5f-b64d9e7c1a0cn%40googlegroups.com.


Re: Model icons

2023-02-23 Thread Jacob Rief
On Thu, Feb 23, 2023 at 7:38 AM Brice Parent  wrote:

> Hello!
>
> Really useful idea, I think! 2 points about it:
>
> 1. Syntax
>
> I would also remove the html from the models, but probably in this way:
> class Hammer(models.Model):
> ...
>
> Meta:
> icon = ModelIcon("🔨")
>
>
> There would be something like
>
> ModelIcon.as_html(self, model_name:str) -> str:
> """returns whatever html should be used in the admin"""
>
>
> or a ModelIcon.set_text(self, text: str) and we'd use a simple
> str(model_icon) in the templates.
>
> In my opinion, Django models shall not have to specify parts of their
representation layer, such as icons.
This shall be left exclusively to the view layer: The ModelAdmin is such a
candidate.

That way, it could be extended easily in a
> FontAwesomeModelIcon("fa-hammer") and a BootstrapModelIcon("bi-hammer") for
> example, and maybe get whatever extra arguments they may need, like
> FontAwesomeModelIcon("fa-hammer", thickness="solid").
>
> I don't like the idea that Django becomes dependent on any
UTF-8-Symbol/Dingbats/Emojis/Glyphicon/Font-Awesome/Bootstrap/Remix/etc-Iconset.
Some Models might have a purpose which can not be mapped to any of those
icons and need to be custom designed.


> 2. Make it more widely useful
> I like the fact that it's in the model itself and not in the modeladmin,
> as it allows to use it elsewhere, like in the __str__ to quickly add this
> visual indication of the class. Boostrap and co would have to provide a
> non-html version of the icon or return an empty string though.
>
> That's a violation of the well established MVC pattern of keeping the
visual part in the view, and the "business model" within the model.

Just my 2 cents
– Jacob

-- 
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/CAJ_HXxpnzW-bA%2BrJwBZC67CRwb0ss%2B0mmT6fZ6VAh1PDuhucGg%40mail.gmail.com.


Re: dynamically added INSTALLED_APPS

2023-02-23 Thread Jörg Breitbart
Ah sorry for the fuzz, I read too much into your idea and jumped to the 
conclusion, that you want to extend INSTALLED_APPS at runtime.


What you describe here

> INSTALLED_APPS = [
>  "django.contrib..."
>  "..."
>  "myapp.core"
> ]
>
> PluginManager.find_apps(INSTALLED_APPS, "myapp.plugins")

makes perfect sense, as it only decorates INSTALLED_APPS very early 
during settings.py loading, so the boostrapping should be fine. I dont 
see any issues with that - beside hiding the explicit loading nature, as 
Jacob pointed out, but thats indeed already an issue baked into python 
with setup.py deps or carelessly pulling untrusted stuff via pip. So 
nope, the explicit nature of INSTALLED_APPS is a "false friend" in terms 
of security concerns from 3rd party modules.


As you already pointed out, the proper app ordering might be a bigger 
issue for an automated app discovery. Not sure how you solved that, this 
might need some tree balance logic, but the question remains, where to 
get the info "xy must be loaded before/after z" from in the first place. 
Ideally apps should be loading position independent, but thats not 
always the case, and you might even run into edge cases, where a proper 
loading strategy cannot be found due to incompatible before/after 
requirements.


Cheers,
Jörg

--
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/32215db2-a151-51ed-a491-eb0d2d7a313f%40netzkolchose.de.


Re: dynamically added INSTALLED_APPS

2023-02-23 Thread Christian González

Am 23.02.23 um 17:09 schrieb Jörg Breitbart:
Ah sorry for the fuzz, I read too much into your idea and jumped to 
the conclusion, that you want to extend INSTALLED_APPS at runtime.

no prob ;-)
As you already pointed out, the proper app ordering might be a bigger 
issue for an automated app discovery. Not sure how you solved that, 
this might need some tree balance logic, but the question remains, 
where to get the info "xy must be loaded before/after z" from in the 
first place. Ideally apps should be loading position independent, but 
thats not always the case, and you might even run into edge cases, 
where a proper loading strategy cannot be found due to incompatible 
before/after requirements.


I am exploring 2 ways of adding app strings to INSTALLED_APPS. Code says 
more than words:


class PluginManager: ... @classmethod def alter_installed_apps(cls, 
installed_apps:list[str], group:str) ->list[str]:
"""Lets plugins update INSTALLED_APPS and add their own apps to it, in 
arbitrary order. Call this method directly after your 
settings.INSTALLED_APPS declaration. """


I'm not sure if altering the passed list is better, or returning a new 
one. would be more explicit to see what it does.


The method

1. searches for an *alter_installed_apps* method in the main plugin 
module, which takes the INSTALLED_APPS as first argument, and calls it. 
So I give the plugin itself the possibility to place itself (and evtl. 
needed other modules) at indexes of the INSTALLED_APPS list *they* need 
and find appropriate. This should work well for many apps that have 
special requirements like "should be placed after 
django.contrib.staticfiles", but does not cover real dependency 
checking, especially does not cover inter-dependencies of 2 plugins - 
the first loaded plugin does not know about the second, as at time of 
calling the first one, INSTALLED_APPS does not contain the second one.


2. if this does not exist, it searches for an INSTALLED_APPS list in the 
main module as stated earlier, for dumb modules that just need to be 
loaded, no matter which order. This list is plainly appended to the main 
INSTALLED_APPS.



At time of calling plugin implementations via their hooks, they provide 
"weight" attrs and get ordered by this attr when iterating over them. So 
each interface hook can have it's own ordering, which works perfectly.


But that doesn't solve the dependency resolution problem of 
INSTALLED_APPS. One of my solutions is: Use Python's way: I declare 
dependencies in pyproject.toml, so dependency resolution is done by pip. 
And in Django, I can already be sure everything is installed as 
intended, and just order INSTALLED_APPS like I want to.


But it's not perfect, I know.

So thanks Jörg for your helpful comment. I wasn't quite sure about if I 
did something stupid.


And thanks for your all engaging in Django, it's really a great piece of 
software.


Yours,

Christian

--
Dr. Christian González
https://nerdocs.at

--
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/dfadb69d-d86e-29c6-a752-6f33cb64c906%40nerdocs.at.