How to additional field to Django Oscar Order model?

I want add additional field to Order model. i have already forked order app. below is the code added in Order model in forked_app Order app.

from django.utils import timezone
from oscar.apps.order.abstract_models import AbstractOrder
from oscar.apps.order.models import *  # noqa isort:skip
from django.db import models


class Order(AbstractOrder):
    status_update_time = models.CharField(max_length=30)

   def save(self, *args, **kwargs):
       self.status_update_time = timezone.now()
       super(Order, self).save(*args, **kwargs)

Below is the error i get while migrations.

class Order(AbstractOrder):
NameError: name 'AbstractOrder' is not defined
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x7f06737e6d08>


RuntimeError: Conflicting 'order' models in application 'order': <class 'oscar.apps.order.models.Order'> and <class 'forked_apps.order.models.Order'>.

Upvotes: 1

Views: 1017

Answers (2)

Mobasshir Bhuiya
Mobasshir Bhuiya

Reputation: 1092

In order to customize models, views and urls, you need to fork an Oscar core app in which model/view resides. Then you should be able to override any model/view classes.

Steps to fork/customize an app:

  1. If you are forking an Oscar app for the first time, then you have to create a root apps-folder in which all your forked apps will exists:

    $ mkdir yourappsfolder $ touch yourappsfolder/init.py

  2. Create a python module with the same ‘app-label’ as the Oscar app:

Ex: Customising oscar.apps.catalogue app

$ mkdir yourappsfolder/catalogue
$ touch yourappsfolder/catalogue/__init__.py
  1. If the Oscar app has a models.py, then you have to create a models.py file in your local app.

    your custom models go here

    from oscar.apps.catalogue.models import *

NOTE: To customise Oscar’s models, you must add your custom one before importing Oscar’s models. Then, your models file will have two models with the same name within an app, Django will only use the first one.

Ex: To add a active field to the product model:

# yourappsfolder/catalogue/models.py
from django.db import models
from oscar.apps.catalogue.abstract_models import AbstractProduct
class Product(AbstractProduct):
    active = models.BooleanField(default=False)
from oscar.apps.catalogue.models import *
  1. Create an ‘admin.py’ file in your local app.

    yourappsfolder/catalogue/admin.py

    from oscar.apps.catalogue.admin import *

  2. Then copy the ‘migrations’ directory from oscar/apps/catalogue and put it into your new local catalogue app.

  3. Added it as Django app by replacing Oscar’s app with your own in INSTALLED_APPS.

    settings.py

    from oscar import get_core_apps INSTALLED_APPS = [ ..., # all your non-Oscar apps ] + get_core_apps(['yourappsfolder.catalogue'])

NOTE: get_core_apps([]) will return a list of Oscar core apps or else if you give a list of your custom apps, they will replace the Oscar core apps.

  1. Finally, create migrations using ‘makemigrations’ management command and apply the migrations by using ‘migrate catalogue’ management command. Then, you can see that a new column is been added to the product model.

Upvotes: 0

Exprator
Exprator

Reputation: 27523

from django.utils import timezone
from oscar.apps.order.abstract_models import AbstractOrder

from django.db import models


class Order(AbstractOrder):
    status_update_time = models.CharField(max_length=30)

   def save(self, *args, **kwargs):
       self.status_update_time = timezone.now()
       super(Order, self).save(*args, **kwargs)

at the end of the models.py file

from oscar.apps.order.models import *  

then try to do makemigrations and then migrate

Upvotes: 4

Related Questions