django-salesman
django-salesman copied to clipboard
Store custom data on Order
Currently, when overriding and expanding your Order model with custom fields (let's say I want to store first_name
and last_name
on my order besides the default email
), everything has to go through the extras
object during checkout. I was wondering if there is (or could be in the future) a more robust way of doing this, as it currently feels like twisting the frameworks arm a bit. Let me clarify.
Say I expand my order model with these fields:
from salesman.orders.models import BaseOrder
class Order(BaseOrder):
first_name = TextField(_("First name"), null=True, blank=True)
last_name = TextField(_("Last name"), null=True, blank=True)
And, after creating a basket I initiate a checkout with this JSON:
{
"email": "[email protected]",
"first_name": "Tim",
"last_name": "van der Linden",
"payment_method": "pay-later",
}
To get the extra fields first_name
and last_name
stored on my order I need to override the populate_from_basket()
method on the Order and add in these two fields:
@transaction.atomic
def populate_from_basket(
self,
basket: BaseBasket,
request: HttpRequest,
**kwargs: Any,
) -> None:
"""
Populate order with items from basket.
Args:
basket (Basket): Basket instance
request (HttpRequest): Django request
"""
from salesman.basket.serializers import ExtraRowsField
if not hasattr(basket, "total"):
basket.update(request)
self.user = basket.user
self.email = basket.extra.pop("email", "")
self.first_name = basket.extra.pop("first_name", "") # <- added in
self.last_name = basket.extra.pop("last_name", "") # <- added in
...
As you can see I need to pop them from the extras object of the basket to store them on the final Order.
I understand that the checkout itself is not a model and is more of a process, your Basket simply gets "transformed" into an Order with the above method. But still it feels strange to pull all of our custom data we wish to capture from the extras
object of the basket.
Is this the intended way? Or should the Basket model be overridden as well and contain mirror fields of the data we want to store on the final Order (eg. a custom Basket model which would also contain a first_name
and last_name
field)?