longclawshop/longclaw

How to extend core components

dtwm opened this issue · 7 comments

dtwm commented

I can't wrap my head around what would be proper way to extend core models and/or alter build-in processes.
Simplest example -- I need to save additional data when creating new order or want to have a foreign key from order to user profile.
The only solid way that I see is custom fork of whole project which isn't that fun.

Hi.
You can use the standard expansion approaches applicable in the Django.
If you need to add options for orders, try to extend the data from the file
https://github.com/JamesRamm/longclaw/blob/master/longclaw/orders/models.py

dtwm commented

thanks for reply.

I'm still not sure what standard approach to use if I want to save foreign key to the user that makes order. I am not so active on related project so might be heading towards a dead end but I ended up reiplementing checkout app and hijacking different longclaw urls.
Next big thing is api and I feel like doing essentially the same.

To look at it, original question might be too broad to have an answer and I'm sorry if it is.

Just a thought (untested but I've seen similar constructs applied to unrelated things)... but couldn't you write a middleware that listens for an order save signal and have access to the request there to create your foreign keys between your custom model, user, and the order?

dtwm commented

thanks, one could do that for small tweaks I suppose. I wouldn't tho, in my cases changes to checkout page grow quite a bit.

Without a more specific example I am not sure how to help. Signals is kind of the way to add pluggable processing in Django.

@thenewguy @dtwm Hello,

In general, the best approach to extend core components in Django is to use Django's built-in mechanisms for customization, such as subclassing or monkey-patching. Here are a few possible ways to extend the Longclaw e-commerce platform:

  1. Subclass the existing model and override the fields and methods you want to change.

For example, to add a foreign key to the user profile on the Order model, you could create a new model called UserProfileOrder that inherits from Order and adds the new field:

from django.db import models
from longclaw.checkout.models import Order

class UserProfileOrder(Order):
    user_profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE)

Then, you can use UserProfileOrder instead of Order in your code, and it will have the additional field.

  1. Use signals to modify existing objects when they are saved or deleted.

For example, to save additional data when creating a new order, you could create a signal handler that listens for the post_save signal on the Order model:

from django.db.models.signals import post_save
from django.dispatch import receiver
from longclaw.checkout.models import Order

@receiver(post_save, sender=Order)
def add_order_metadata(sender, instance, created, **kwargs):
    if created:
        # Add your additional data to the order here
        instance.additional_data = ...
        instance.save()

This will automatically run the add_order_metadata function every time an order is saved, and you can use it to add any additional data you need.

  1. Monkey-patch the existing code to modify the behavior of existing methods or functions.

For example, to modify the behavior of the create_order function in the checkout.views module, you could override it in your own code:

from longclaw.checkout.views import create_order as original_create_order

def create_order(request):
    # Add your custom logic here
    ...
    # Call the original function to create the order
    return original_create_order(request)

This will intercept calls to the create_order function and allow you to modify the behavior before and after the original function is called.