Django Design Models for Overriding Models

I am working on an e-commerce infrastructure for Django. The main goal of the project is to provide minimal functionality in terms of models and views, instead allowing library users to expand or replace components with their own.

The reason for this is that trying to develop a one-time e-commerce solution leads to overly complex code that is often far from optimal.

One approach to solving this problem is to use control inversion through the Django settings file or import hacks, but I ran into some problem due to the way Django registers its models.

The e-commerce framework provides a bunch of abstract models, as well as specific versions in {app_label} /models.py. Views use the Django get_model(app_label,model) function to return the model class without the need for hard-coding the link.

This approach has some problems:

  • Users should imitate the structure of the application framework, i.e. app_label, and effectively replace our version of the application with their own

  • Due to how the admin site works, looking for admin.py in each installed application, they must imitate or explicitly import the frame admin classes in order to use them. But, importing them, the register method is called, so they must be unregistered if the user wants to configure them.

  • The user should be extremely careful in how to import specific models from the main structure. This is because the metaclass of the base Django model automatically registers the model with the application cache as soon as the class definition is read (for example, with __new__ ), and the first model registered on a particular label is the one with which you are stuck. Therefore, you must define all of your overridden models before importing any of the main models. This means that in the end, you are faced with messy situations with the presence of a heap of imports at the bottom of your modules, and not at the top.

My thinking is to go further down the blood supply with inversion control:

  • All links to the main components (models, views, admin, etc.) are replaced by IoC container calls

  • For all major (e-commerce models) replace the use of the metaclass of the base Django model for those who do not have automatic registration of models, and then the box explicitly registers them at startup.

My question is:

Is there a better way to solve this problem? The goal is to simplify the configuration of the framework and redefine functionality without learning many annoying tricks. The key seems to apply to the models and admin site.

I understand that using an IoC container is not a common pattern in the Django world, so I want to avoid it if possible, but seems like the right solution.

+4
source share
1 answer

Have you considered code from other projects with a similar approach? Not sure if this method meets your needs, but pay attention to the django-shop code.

This structure provides the basic logic, allowing you to customize the logic if necessary.

customize through models

e.g. see productmodel.py

 #============================================================================== # Extensibility #============================================================================== PRODUCT_MODEL = getattr(settings, 'SHOP_PRODUCT_MODEL', 'shop.models.defaults.product.Product') Product = load_class(PRODUCT_MODEL, 'SHOP_PRODUCT_MODEL') 

configure via logic / url

for example, see the simplevariation-plugin store. It extends the logic basket, so it connects via urlpattern:

 (r'^shop/cart/', include(simplevariations_urls)), (r'^shop/', include(shop_urls)), 

and expands views: ...

 from shop.views.cart import CartDetails class SimplevariationCartDetails(CartDetails): """Cart view that answers GET and POSTS request.""" ... 

The structure provides several points for connection, the simple plug-in mentioned above provides a cart modifier:

 SHOP_CART_MODIFIERS = [ ... 'shop_simplevariations.cart_modifier.ProductOptionsModifier', ... ] 

I am worried that this explanation is not very clear, it is difficult to briefly generalize this concept. But look at the django-shop project and some of its extensions: ecosystem

+1
source

Source: https://habr.com/ru/post/1395209/


All Articles