Giter Site home page Giter Site logo

cartridge's Introduction

https://secure.travis-ci.org/stephenmcd/cartridge.png?branch=master

Created by Stephen McDonald

Overview

Cartridge is a shopping cart application built using the Django framework. It is BSD licensed, and designed to provide a clean and simple base for developing e-commerce websites. It purposely does not include every conceivable feature of an e-commerce website; instead, Cartridge focuses on providing core features common to most e-commerce websites.

This specific focus stems from the idea that every e-commerce website is different, is tailored to the particular business and products at hand, and should therefore be as easy to customize as possible. Cartridge achieves this goal with a code-base that is as simple as possible and implements only the core features of an e-commerce website.

Cartridge extends the Mezzanine content management platform. A live demo of Cartridge can be found by visiting the Mezzanine live demo.

Features

  • Hierarchical categories
  • Easily configurable product options (colours, sizes, etc.)
  • Hooks for tax/shipping calculations and payment gateways
  • Sale pricing
  • Promotional discount codes
  • PDF invoice generation (for packing slips)
  • Stock control
  • Product popularity
  • Thumbnail generation
  • Built-in test suite
  • Separation of presentation (no embedded markup)
  • Smart categories (by price range, colour, etc)
  • Registered or anonymous checkout
  • Configurable number of checkout steps
  • Denormalised data for accessibility and performance
  • Authenticated customer accounts with transaction history

Dependencies

Cartridge is designed as a plugin for the Mezzanine content management platform, and therefore requires Mezzanine to be installed. The integration of the two applications should occur automatically by following the installation instructions below.

Installation

The easiest method is to install directly from PyPI using pip by running the command below, which will also install the required dependencies mentioned above:

$ pip install -U cartridge

Otherwise, you can download Cartridge and install it directly from source:

$ python setup.py install

Once installed, the command mezzanine-project can be used to create a new Mezzanine project, with Cartridge installed, in similar fashion to django-admin.py:

$ mezzanine-project -a cartridge project_name
$ cd project_name
$ python manage.py createdb --noinput
$ python manage.py runserver

Here we specify the -a switch for the mezzanine-project command, which tells it to use an alternative package (cartridge) for the project template to use. Both Mezzanine and Cartridge contain a project template package containing the settings.py and urls.py modules for an initial project. If you'd like to add Cartridge to an existing Mezzanine or Django project, you'll need to manually configure these yourself. See the FAQ section of the Mezzanine documentation for more information.

Note

The createdb command is a shortcut for using Django's migrate command, which will also install some demo content, such as a contact form, image gallery, and more. If you'd like to omit this step, use the --nodata option with createdb.

You should then be able to browse to http://127.0.0.1:8000/admin/ and log in using the default account (username: admin, password: default). If you'd like to specify a different username and password during set up, simply exclude the --noinput option included above when running createdb.

Contributing

Cartridge is an open source project managed using both the Git and Mercurial version control systems. These repositories are hosted on both GitHub and Bitbucket respectively, so contributing is as easy as forking the project on either of these sites and committing back your enhancements.

Please note the following guidelines for contributing:

  • Contributed code must be written in the existing style. For Python (and to a decent extent, JavaScript as well), this is as simple as following the Django coding style and (most importantly) PEP 8. Front-end CSS should adhere to the Bootstrap CSS guidelines.
  • Contributions must be available on a separately named branch based on the latest version of the main branch.
  • Run the tests before committing your changes. If your changes cause the tests to break, they won't be accepted.
  • If you are adding new functionality, you must include basic tests and documentation.

Here's a quick start to hacking on Cartridge after forking it on GitHub, by using the internal "project_template" as your current project:

$ git clone https://github.com/your-github-username/cartridge/
$ cd cartridge
$ git checkout -b your-new-branch-name
$ cp cartridge/project_template/project_name/local_settings.py{.template,}
$ python setup.py develop
$ python cartridge/project_template/manage.py createdb --noinput
$ python cartridge/project_template/manage.py runserver

"hack hack hack"

$ python setup.py test
$ git commit -am "A message describing what you changed."
$ git push origin your-new-branch-name

Note

Cartridge's development branch often relies on features that exist in Mezzanine's development branch, but haven't yet made it into an official release. To install Mezzanine's development version in your environment, run:

$ pip install --upgrade git+https://github.com/stephenmcd/mezzanine.git#egg=Mezzanine

Language Translations

Cartridge makes full use of translation strings, which allow Cartridge to be translated into multiple languages using Django's internationalization methodology. Translations are managed on the Transiflex website but can also be submitted via GitHub or Bitbucket. Consult the documentation for Django's internationalization methodology for more information on creating translations and using them.

Third-party Modules

The following modules have been developed outside of Cartridge. If you have developed a module to integrate with Mezzanine or Cartridge, and would like it listed in the documentation, send an email to the mezzanine-users mailing list. You can also add modules to the Mezzanine Grid on djangopackages.com.

Donating

If you would like to make a donation to continue development of Cartridge, you can do so via the Mezzanine Project website.

Support

To report a security issue, please send an email privately to [email protected]. This gives us a chance to fix the issue and create an official release prior to the issue being made public.

For all other Cartridge support, the primary channel is the mezzanine-users mailing list. Questions, comments, and all related discussions take place here amongst knowledgeable members of the community.

If you're certain you've come across a bug, then please use the GitHub issue tracker. It's crucial that enough information is provided to reproduce the bug. This includes things such as the Python stack trace generated by error pages, as well as other aspects of the development environment used, such as operating system, database, Python version, etc. If you're not sure you've found a reproducable bug, then please try the mailing list first.

Finally, feel free to drop by the #mezzanine IRC channel on Freenode, for a chat!

Communications in all Cartridge and Mezzanine spaces are expected to conform to the Django Code of Conduct.

Sites Using Cartridge

cartridge's People

Contributors

alexhill avatar averagehuman avatar bornazadeh avatar dfalk avatar dsanders11 avatar ewingrj avatar goodtune avatar henri-hulski avatar jbmckeon avatar jcartmell avatar jerivas avatar joshcartme avatar kenbolton avatar kniyl avatar mik3y avatar molokov avatar mrbiscuits avatar owenh000 avatar pokoli avatar ptitluc avatar randomjo avatar rosslaird avatar ryneeverett avatar sebasmagri avatar sjkingo avatar slav0nic avatar stephenmcd avatar thomaswajs avatar uranusjr avatar wrwrwr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cartridge's Issues

Applying more than one discount code can "stack" in unexpected ways

The shop order only supports a single discount code, but depending on the behaviour of the discount codes it is possible for a user to apply more than one.

Application of a second discount code should cancel the first.

For example:
I created two discount codes - FREESHIP gave free shipping, and 5OFF gave $5 off any item.

If I apply one and then the other, both would take effect - giving the user $5 off each item /and/ free shipping. However, as only one code is stored with the order, the uses_remaining of the one applied second would be decremented, but not the first.

Either only a single discount code should apply (so when the second is applied, the first's effect is cancelled) or we may have to think about how to apply multiple codes to the cart/order.

add image for category

How about to add an image field for Category, which may be used for displaying in category list or brand list?

memcached - ServerError: error 10 from memcached_set: SERVER ERROR

When I want to view a product with a lot of product variants (about 1000) and caching with memcached is enabled I get this error:

[04/Jun/2013 14:59:31] ERROR [django.request:212] Internal Server Error: /shop/product/зигзаг-полотенцесушитель/
Traceback (most recent call last):
  File "/home/inox-t/.virtualenvs/prj_inox/lib/python2.6/site-packages/django/core/handlers/base.py", line 187, in get_response
    response = middleware_method(request, response)
  File "/home/inox-t/.virtualenvs/prj_inox/lib/python2.6/site-packages/mezzanine/core/middleware.py", line 134, in process_response
    response.add_post_render_callback(_cache_set)
  File "/home/inox-t/.virtualenvs/prj_inox/lib/python2.6/site-packages/django/template/response.py", line 92, in add_post_render_callback
    callback(self)
  File "/home/inox-t/.virtualenvs/prj_inox/lib/python2.6/site-packages/mezzanine/core/middleware.py", line 132, in 
    _cache_set = lambda r: cache_set(cache_key, r.content, timeout)
  File "/home/inox-t/.virtualenvs/prj_inox/lib/python2.6/site-packages/mezzanine/utils/cache.py", line 37, in cache_set
    return cache.set(_hashed_key(key), packed, real_timeout)
  File "/home/inox-t/.virtualenvs/prj_inox/lib/python2.6/site-packages/django/core/cache/backends/memcached.py", line 71, in set
    self._cache.set(key, value, self._get_memcache_timeout(timeout))
ServerError: error 10 from memcached_set: SERVER ERROR

here my cache settings:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '127.0.0.1:11211',
        "BINARY" : True,
        'OPTIONS': {  # Maps to pylibmc "behaviors"
            'tcp_nodelay': True,
            'ketama': True,           
        }
   }
}

PYLIBMC_MIN_COMPRESS_LEN=2048

I googled a bit about this error... it seems it is related to 1M limit of memcached value.
I tried with PYLIBMC_MIN_COMPRESS_LEN set and without it, same results

Sale save method has incorrect exception handling.

Hi Stephen.

I am pretty sure the exception handling in cartridge/shop/models.py Sale.save() is incorrect.

            except OperationalError:
                # Work around for MySQL which does not allow update
                # to operate on subquery where the FROM clause would
                # have it operate on the same table.
                #
                # http://dev.mysql.com/
                # doc/refman/5.0/en/subquery-errors.html
                try:
                    for priced in priced_objects.filter(**extra_filter):
                        for field, value in update.items():
                            setattr(priced, field, value)
                        priced.save()  <- save throw an Exception
                except Warning:
                    pass
            except Warning:
                pass

Currently if the priced.save() throws an exception the out loop will not complete and the any product/variation that have not been process won't be updated. It would be better to put the exception handling right around the save call, ie:

try:
priced.save()
except Warning:
pass

Of course I could be wrong. Thanks for you time.

Regards,
Damian

issues installing cartridge from pypi

Freshy installed from scratch following the installation guide.

python manage.py createdb fails as follows.

/usr/src/cartridge-env/lib/python2.7/site-packages/mezzanine/utils/conf.py:48: UserWarning: You haven't defined the ALLOWED_HOSTS settings, which Django 1.5 requires. Will fall back to the domains configured as sites.
  warn("You haven't defined the ALLOWED_HOSTS settings, which "
Traceback (most recent call last):
  File "manage.py", line 28, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/src/cartridge-env/lib/python2.7/site-packages/django/core/management/__init__.py", line 453, in execute_from_command_line
    utility.execute()
  File "/usr/src/cartridge-env/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/src/cartridge-env/lib/python2.7/site-packages/django/core/management/__init__.py", line 272, in fetch_command
    klass = load_command_class(app_name, subcommand)
  File "/usr/src/cartridge-env/lib/python2.7/site-packages/django/core/management/__init__.py", line 77, in load_command_class
    module = import_module('%s.management.commands.%s' % (app_name, name))
  File "/usr/src/cartridge-env/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/usr/src/cartridge-env/lib/python2.7/site-packages/mezzanine/core/management/__init__.py", line 12, in <module>
    from mezzanine.utils.tests import copy_test_to_media
  File "/usr/src/cartridge-env/lib/python2.7/site-packages/mezzanine/utils/tests.py", line 10, in <module>
    from mezzanine.conf import settings
  File "/usr/src/cartridge-env/lib/python2.7/site-packages/mezzanine/conf/__init__.py", line 140, in <module>
    module = import_module(app)
  File "/usr/src/cartridge-env/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
ImportError: No module named shop

Trouble with external payment services

Hey,

the order will be saved with the last step with a post request, but external payment services don't send a post request when returning to the site. In repository cartridge-payments (https://github.com/explodes/cartridge-payments) it's solved by saving the order in the penultimate step.

But if I abort the order in paypal (for example), the order is still saved.

I suggest to move the saving-code to the complete-function and make it only visible after visited step 3. A session variable could make sure to save and send email just one time.

What do you think?

Discount code uses_remaining is never decremented

Small bug in Order.complete():
https://github.com/stephenmcd/cartridge/blob/master/cartridge/shop/models.py#L474-L501

The fields from self.session_fields are deleted at the top of the function, but we don't get the discount_code out of the session until later in the function - and discount code is one of those deleted as it's listed in self.session_fields.

This way, the uses_remaining field is never decremented when the discount code is used, as it will always be None.

Simple enough to fix by some rearrangement of lines in the function.

Reservations / Bookings product type

I'm building a site using Mezzanine + Cartridge and would like to one way or another implement a reservation system / booking tool using Cartridge.

Does someone already have anything like this or any experiences / opinions on whether the Cartridge data model would bend to this kind of product? In this case I would be using it for a cottage reservation system, so customers need to be able to reserve cottages for a variable amount of night and also select extra products (sheets, breakfast, etc).

Thanks for any tips!

Cart objects may stuck in limbo

Easiest reproduction:

  1. Build a shop with only one available product variation (call it product Foo).
  2. User A logs in, add all Foo items in stock to the cart.
  3. User A logs out (clearing the session).
  4. User B logs in and tries to add a Foo item to the cart. This will not work because all Foo items are in A's cart. Makes sense.
  5. Wait for SHOP_CART_EXPIRY_MINUTES.
  6. User B tries to add Foo to the cart again. This will still fail, even though the cached Cart object should have expired.

At this point, no-one will be able to buy any Foos anymore, unless you trigger cache cleanup in some way. But the cache cleanup is triggered during CartManager.from_request only when there is another session containing a cart reference. In the above mentioned scenario, no one contains such a reference anymore after step 3, making the cached cart item stuck in limbo, and can neither be accessed nor deleted.

The relevant source (cartridge/shop/manages.py, line 25 to 34)

if cart_id:
    try:
        cart = self.get(last_updated__gte=expiry_time, id=cart_id)
    except self.model.DoesNotExist:
        request.session["cart"] = None
    else:
        # Update timestamp and clear out old carts.
        cart.last_updated = n
        cart.save()
        self.filter(last_updated__lt=expiry_time).delete()

Is there a reason why the current implementation is like this? I feel that you can clean caches even when you don't create a new cache item

if cart_id:
    try:
        cart = self.get(last_updated__gte=expiry_time, id=cart_id)
    except self.model.DoesNotExist:
        request.session["cart"] = None
    else:
        # Update timestamp and clear out old carts.
        cart.last_updated = n
        cart.save()
self.filter(last_updated__lt=expiry_time).delete()

Or is there anything I missed?

Migration 0001 imports non-existent method

Looks like commit 832032f broke south migration 0001:

$ manage.py migrate
[...]
  File "/home/ubuntu/.virtualenvs/pkb/local/lib/python2.7/site-packages/South-0.7.6-py2.7.egg/south/migration/migrators.py", line 175, in _run_migration
    migration_function()
  File "/home/ubuntu/.virtualenvs/pkb/local/lib/python2.7/site-packages/South-0.7.6-py2.7.egg/south/migration/migrators.py", line 57, in <lambda>
    return (lambda: direction(orm))
  File "/home/ubuntu/.virtualenvs/pkb/local/lib/python2.7/site-packages/Cartridge-0.8.1-py2.7.egg/cartridge/shop/migrations/0001_initial.py", line 233, in forwards
    from cartridge.shop.management import create_initial_product
ImportError: cannot import name create_initial_product

Maybe just a matter of renaming the method, though IMO it'd be better still to avoid sneaking this hook into the migration (introduced in 52fa3f7). In addition to making the migration brittle to external changes as above, the forced prompt interferes with non-interactive migrate (deployment scripts, continuous builds, etc).

NoReverseMatch at /account/update

Hi,

Upgrade to latest Mezzanine, 1.1.3.
Ran into an error when doing the following in Cartridge:

  • Add item to basket
  • View cart
  • Checkout
  • Signup before checkout (anon checkout disabled)
  • click on user name to view order history and ran into an error

Stacktrace:
http://dpaste.com/764168/

No-select type of ProductVariation

In some scenarios, the customer himself needs to insert additional information, which is nearly impossible to predict, so the CharField text input is needed.

Is there any plans to implement this kind of functionality?

Thank You

provide a way to disable default category and product installation

Stephen,

For automated deployment, I need a way to disable the default category and product installation for the demonstration store. Look for a setting in settings.py, else ask the user if interactive, else do not install demo data is what the patch below implements. I can submit a pull request, but there are a couple of different ways to nest the conditional logic, so wanted to get your comments first.

Regards,
Brian

This issue is similar to the Mezzanine issue #222.
stephenmcd/mezzanine#222

Committed fix in my fork:
https://github.com/nimbis/cartridge/commit/20474376662790a4e3d2f50f97ed8c9137e15063

diff --git a/cartridge/shop/management/__init__.py b/cartridge/shop/management/__init__.py
index f671f2f..eae1747 100644
--- a/cartridge/shop/management/__init__.py
+++ b/cartridge/shop/management/__init__.py
@@ -11,7 +11,9 @@ from cartridge.shop import models as shop_app

 def create_initial_product(app, created_models, verbosity, **kwargs):
     if settings.DEBUG and Product in created_models:
-        if kwargs.get("interactive"):
+        if not getattr(settings, 'CARTRIDGE_INSTALL_INITIAL_CONTENT', False):
+            return
+        elif kwargs.get("interactive"):
             confirm = raw_input("\nWould you like to install an initial "
                                 "Category and Product? (yes/no): ")
             while True:
@@ -20,6 +22,8 @@ def create_initial_product(app, created_models, verbosity, **kwargs):
                 elif confirm == "no":
                     return
                 confirm = raw_input("Please enter either 'yes' or 'no': ")
+        else:
+            return
         if verbosity >= 1:
             print
             print "Creating initial Category and Product ..."

Discount codes apply per item, but uses_remaining apply per order

The current discount code feature allows a reduction in price/percentage on a per-item basis for selected products/categories, and also allows you to limit how many times the code is used with 'uses_remaining'.

However, the uses_remaining field is only decremented by 1 at the end of an order, even if the code was used for multiple items.

For example, if I create a code 5OFF to give $5 off each item in an order, but limit it to 2 uses only, a user can still order 3 or more items (either multiple of the same, or different items) and get $5 off each one, even though technically the code should only apply to the first two items.

Is the currently behaviour the intended behaviour? Or should we fix this so that 'uses_remaining' applies to the number of items the code applies to?

Add ability to customize order receipt

Right now, the order receipt template file name is hard-coded into checkout.py. I'd like to have a setting like the one for payment handler for the receipt handler.

getting error with manage.py syncdb using postgresql_psycopg2

It stops after 'Creating table shop_product' and throws some errors, the last of which is this:

File "(mypath)/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute return self.cursor.execute(query, args) django.db.utils.DatabaseError: NUMERIC scale 127 must be between 0 and precision 10

I'm guessing it has something to do with an Integer field in the cartridge model, but I'm not sure which one. I'm running Mezzanine .8 runs just fine without Cartridge. So this issue is isolated to setting up a Cartridge project.

Naming of Category

Hi,

I'm currently working on a recipe-sharing project. It has a similar model structure with Cartridge: A Displayable subclass for recipe, and a category page model to show a list of recipes. Cartridge works fine with it, of course, but I'm facing a little problem on admin customization — Cartridge's category model is named Category (with verbose names "Category/Categories"), and shows up in the Page admin's add menu as "Category," which to me sounds a bit too generic than it should. Of course, you can get what you want once you understands this, but still it might confuses people not familiar with Cartridge (and/or Mezzanine), which is not good since a CMS admin is supposed to be usable for non-programmers as well. Even programmers might need to spend some unneeded brain power trying to resolve between different kinds of categories if they have a more complicated structure.

So basically I'm purposing a change of name for model Category. It'd be good just changing the verbose names to Product category/categories. Refactoring model names would be more work, and you can always work around it by using from cartridge.shop.models import Category as ProductCategory if you need to (do you ever?).

Any thoughts?

DjangoUnicodeDecodeError when saving product with variations (in admin)

I created completely localized website in russian, so everything is in russian including product names, product variations and the SHOP_OPTION_TYPE_CHOICES

I entered the following in settings.py:

SHOP_OPTION_TYPE_CHOICES = (
(1, "Размер"),
(2, "Материал"),
)

Everything works fine until I try to create new variations and save the product with new variations in the admin. I press "save" and get DjangoUnicodeDecodeError.
So, somewhere there should be a bug. Hope the traceback below will be enough to indentify it.

Environment:


Request Method: POST
Request URL: http://localhost:8000/admin/shop/product/9/

Django Version: 1.5.1
Python Version: 2.7.3
Installed Applications:
('mezzanine.boot',
 'theme1',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.redirects',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.sitemaps',
 'django.contrib.staticfiles',
 'cartridge.shop',
 'mezzanine.conf',
 'mezzanine.core',
 'mezzanine.generic',
 'mezzanine.blog',
 'mezzanine.forms',
 'mezzanine.pages',
 'mezzanine.galleries',
 'mezzanine.accounts',
 'filebrowser_safe',
 'grappelli_safe',
 'django.contrib.admin',
 'django.contrib.comments')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.redirects.middleware.RedirectFallbackMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'cartridge.shop.middleware.ShopMiddleware',
 'mezzanine.core.request.CurrentRequestMiddleware',
 'mezzanine.core.middleware.TemplateForDeviceMiddleware',
 'mezzanine.core.middleware.TemplateForHostMiddleware',
 'mezzanine.core.middleware.AdminLoginInterfaceSelectorMiddleware',
 'mezzanine.core.middleware.SitePermissionMiddleware',
 'mezzanine.pages.middleware.PageMiddleware')


Traceback:
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  115.                         response = callback(request, *callback_args, **callback_kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
  372.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  89.         response = view_func(request, *args, **kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
  202.             return view(request, *args, **kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  25.             return bound_func(*args, **kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  21.                 return func(self, *args2, **kwargs2)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/db/transaction.py" in inner
  223.                 return func(*args, **kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in change_view
  1107.                 change_message = self.construct_change_message(request, form, formsets)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in construct_change_message
  696.                                              'object': force_text(changed_object)})
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/utils/encoding.py" in force_text
  115.             raise DjangoUnicodeDecodeError(s, *e.args)

Exception Type: DjangoUnicodeDecodeError at /admin/shop/product/9/
Exception Value: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128). You passed in  ()

Migration to BS3

Hello!

I made a BS3 migration for cartridge, here you can see a demo:

http://test.euve32413.serverloft.de/

One problem left: I don't know why the error messages appears more than one time, please try it out.

If this is ok, I'll love to make a pull request :)

cartridge sales + mysql 1093 error

Hi everybody,

I have the following MySQL error when working on a Sale object in cartridge:
(1093, "You can't specify target table 'shop_product' for update in FROM clause")

It looks like if it is the same error mentioned in the following post:
https://groups.google.com/forum/?fromgroups=#!topic/mezzanine-users/lD0JiWN3HL4

The issue occurs when trying to save a new Sale object with Active as True or setting Active as True on an existing Sale object.
(Sale with at least 1 category selected and discount in either percent of fixed value).

I have created a new fresh install according to the doc just to test it again but the problem occurs again.

It occurs also when creating initial category and Product during DB creation:
https://groups.google.com/forum/?fromgroups=#!searchin/mezzanine-users/1093/mezzanine-users/_BCXzBZqb1s/Kzo4KDwjqooJ

But still the error occurs when setting a Sale to True even if no initial data are created.

shop.models.Sale actually mentions MySQL errors so it looked liked it has been fixed already but I still got the error.

ubuntu 10.04
Python 2.6.5
virtualenv-1.7.1.2
Cartridge-0.6.0
Mezzanine-1.2.4
Mysql_python-1.2.4

For now I have switched to Postgresql and everything is working fine.

Thanks!
David

Orderable product options

The dropdown list with product variations on the product page is unsorted. I have product variations which are numbers, so it is not a localization or NLS issue (the site is in russian)
Attached a picture of dropdown list and a picture from admin showing product options (properly sorted when I click on "name" column header)

screenshot from 2013-06-03 15 41 13_v1

screenshot from 2013-06-03 15 39 16

cannot import name DynamicInlineAdmin

hello,

this morning i installed mezzanine and cartridge ( from github)

mezzanine started ok presenting the default page on the browser.
howerver, in a second project directory, using mezzanine and cartridge, the following error occurred.
i also noticed that the the database configuration entries in settings.py were ignored.

the full error and trace message is a here https://gist.github.com/961875

regards

john

the host is gentoo linux with python 2.7.

ImportError at /

cannot import name DynamicInlineAdmin

Request Method: GET
Request URL: http://blackhole:9876/
Django Version: 1.3
Exception Type: ImportError
Exception Value:

cannot import name DynamicInlineAdmin

Exception Location: /usr/lib/python2.7/site-packages/Cartridge-0.2-py2.7.egg/cartridge/shop/admin.py in , line 8
Python Executable: /usr/bin/python2.7
Python Version: 2.7.1
Python Path:

['../../../mezzanine',
'../../../mezzanine',
'/home/john/projects/kmbooks',
'/usr/lib/python2.7/site-packages/setuptools-0.6c12dev_r85381-py2.7.egg',
'/usr/lib/python2.7/site-packages/DateTime-2.12.6-py2.7.egg',
'/usr/lib/python2.7/site-packages/pytz-2010o-py2.7.egg',
'/usr/lib/python2.7/site-packages/zope.interface-3.6.1-py2.7-linux-i686.egg',
'/usr/lib/python2.7/site-packages/hmac-20101005-py2.7.egg',
'/usr/lib/python2.7/site-packages/hashlib-20081119-py2.7-linux-i686.egg',
'/usr/lib/python2.7/site-packages/BeautifulSoup-3.2.0-py2.7.egg',
'/usr/lib/python2.7/site-packages/CherryPy-3.1.2-py2.7.egg',
'/usr/lib/python2.7/site-packages/ClientForm-0.2.10-py2.7.egg',
'/usr/lib/python2.7/site-packages/yolk-0.4.1-py2.7.egg',
'/usr/lib/python2.7/site-packages/distribute-0.6.14-py2.7.egg',
'/usr/lib/python2.7/site-packages/pythonutils',
'/usr/lib/python2.7/site-packages/configobj-4.7.0-py2.7.egg',
'/usr/lib/python2.7/site-packages/PathUtils-0.8.2-py2.7.egg',
'/usr/lib/python2.7/site-packages/odict-1.4.1-py2.7.egg',
'/usr/lib/python2.7/site-packages/pywsgi-0.9.0-py2.7.egg',
'/usr/lib/python2.7/site-packages/imap_utils-0.4-py2.7.egg',
'/usr/lib/python2.7/site-packages/IMAPClient-0.6.2-py2.7.egg',
'/usr/lib/python2.7/site-packages/IMDbPY-4.6-py2.7-linux-i686.egg',
'/usr/lib/python2.7/site-packages/lxml-2.3beta1-py2.7-linux-i686.egg',
'/usr/lib/python2.7/site-packages/sqlalchemy_migrate-0.6-py2.7.egg',
'/usr/lib/python2.7/site-packages/SQLAlchemy-0.6.5-py2.7.egg',
'/usr/lib/python2.7/site-packages/SQLObject-0.16dev_r4327-py2.7.egg',
'/usr/lib/python2.7/site-packages/Tempita-0.5dev-py2.7.egg',
'/usr/lib/python2.7/site-packages/decorator-3.2.1-py2.7.egg',
'/usr/lib/python2.7/site-packages/FormEncode-1.2.3dev-py2.7.egg',
'/usr/lib/python2.7/site-packages/threadpool-1.2.7-py2.7.egg',
'/usr/lib/python2.7/site-packages/pip-0.8.2-py2.7.egg',
'/usr/lib/python2.7/site-packages/grappelli_safe-0.1.5-py2.7.egg',
'/usr/lib/python2.7/site-packages/filebrowser_safe-0.1.1-py2.7.egg',
'/usr/lib/python2.7/site-packages/Mezzanine-0.11-py2.7.egg',
'/usr/lib/python2.7/site-packages/Cartridge-0.2-py2.7.egg',
'/usr/lib/python2.7',
'/usr/lib/python27.zip',
'/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/usr/lib/python2.7/site-packages',
'/usr/lib/python2.7/site-packages/FontTools',
'/usr/lib/python2.7/site-packages/PIL',
'/usr/lib/python2.7/site-packages/gtk-2.0',
'/usr/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg-info',
'/usr/lib/portage/pym']

Server time: Mon, 9 May 2011 10:54:13 +1000

Trying to delete image for product - throws validation error

While trying to delete image for a product, a validation error is thrown from the save_formset method in ProductAdmin. I have somewhat modified the cartridge code, but was able to replicate this error on the cartridge demo site admin as well.

error when python manage.py syncdb

python manage.py syncdb
Error: One or more models did not validate:
shop.product: "unit_price": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.product: "sale_price": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.productvariation: "unit_price": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.productvariation: "sale_price": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.order: "shipping_total": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.order: "item_total": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.order: "discount_total": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.order: "total": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.cartitem: "unit_price": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.cartitem: "total_price": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.orderitem: "unit_price": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.orderitem: "total_price": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.sale: "discount_deduct": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.sale: "discount_exact": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.discountcode: "discount_deduct": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.discountcode: "discount_exact": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.
shop.discountcode: "min_purchase": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.

Custom Shipping Details Not Working

With a clean install of Cartridge I can go to shop, add the Django Pony, checkout, add Billing Details, uncheck "My delivery details are the same as my billing details" add custom delivery details, and it will show the correct items in the "POST" request on the next page but then it reverts all items in shipping_details to the same as billing_details. Something on the server is simply using billing details as shipping no matter what.

big product foto doesn't scroll

Uploading a big product image (image heigh > screen height) works.
Reduced image, 199x300 px displayed on product page, that's OK
When I click on the image, the original (big) image displayed over the product page. It doesn't fit on the screen, browser shows vertical scrollbar. Perfect.

Now when I try to scroll, the background (product) page is moving, not the image!
There is no way to see the lower part of the big image.
I tested on the demo on http://mezzanine.jupo.org/

MultiValueDictKeyError: "Key 'step' not found

On /shop/checkout occasionally my users are getting an error. The error log shows this in the traceback:

Traceback (most recent call last):

File "/virtualenv/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/core/handlers/base.py", line 111, in get_response
response = callback(request, _callback_args, *_callback_kwargs)

File "/virtualenv/src/cartridge/cartridge/shop/views.py", line 306, in checkout_steps
form = OrderForm(request, step, initial=initial, data=data)

File "/virtualenv/src/cartridge/cartridge/shop/forms.py", line 304, in init
if data is not None and int(data["step"]) != step:

File "/virtualenv/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/utils/datastructures.py", line 256, in getitem
raise MultiValueDictKeyError("Key %r not found in %r" % (key, self))

MultiValueDictKeyError: "Key 'step' not found in <QueryDict: {u'shipping_detail_country': [u'USA'], u'card_ccv': [u'xxx'], u'additional_instructions': [u''], u'billing_detail_city': [u'Las Vegas'], u'billing_detail_country': [u'USA'], u'shipping_detail_phone': [u'xxx-xxx-xxxx'], u'shipping_detail_city': [u'Las Vegas'], u'shipping_detail_postcode': [u'46714'], u'billing_detail_phone': [u'xxx-xxx-xxxx'], u'shipping_detail_last_name': [u'xxxx'], u'card_expiry_month': [u'xx'], u'billing_detail_street': [u'xxxx'], u'shipping_detail_first_name': [u'xxx'], u'billing_detail_last_name': [u'xxx'], u'card_expiry_year': [u'xxxx'], u'csrfmiddlewaretoken': [u'3eae081aeb54656ce0f4e599dbb4fcc0'], u'billing_detail_postcode': [u'46714'], u'card_name': [u'xxxx'], u'fr_shipping': [u'1'], u'shipping_detail_state': [u'Nevada'], u'billing_detail_state': [u'Nevada'], u'billing_detail_first_name': [u'xxx'], u'shipping_detail_street': [u'xxxx'], u'billing_detail_email': [u'[email protected]'], u'card_type': [u'Visa'], u'submit.x': [u'37'], u'submit.y': [u'18'], u'card_number': [u'xxxxx']}>"

Really quite confused on what might be causing the error. I am using the latest versions, I believe pulled from bitbucket.

pdf invoice : missing pip dependency ?

On a fresh Cartridge install (0.8.2) included in a existing Mezzanine project, I had the following error when asking to the pdf invoice version :

ImportError at /shop/invoice/2/
No module named reportlab.lib.units
Request Method: GET
Request URL:    http://localhost:8000/shop/invoice/2/?format=pdf
Django Version: 1.5.1
Exception Type: ImportError
Exception Value: No module named reportlab.lib.units

To fix a the issue, I just had to do :

pip install reportlab

Did I miss something or is the dependency missing in the python egg ?

regards,
Luc

Handlers skipped when returning to existing checkout step

As reported here:

https://groups.google.com/forum/#!topic/mezzanine-users/D5Wh5iTH2Aw

We recently added handling in the checkout steps to support leaving at a particular step, browsing the site further, then returning to the last step the user was at - I suspect this is the cause of one or more "handler" style functions not being called, since in the described case, the first step is skipped.

Perhaps we simply need to call the handler functions at each checkout step.

When will a new version be released?

Hi,

I know this isn't really a bug report and I apologize for it. Please feel free to close this issue. I just wanted to contact you about the next release. I find the optional wishlist feature controlled by the SHOP_USE_WISHLIST setting very useful, but it's only available from the git version. I'm deploying my webapp on Openshift and would really like to be able to use a released version. Thank you!

Check if field exists in session before deleting

With the settings SHOP_CHECKOUT_FORM_CLASS, user might be removing some of the fields such as the cc in their custom checkout form. This would raise KeyError when cartridge try to remove the field in the session:-

--- a/cartridge/shop/views.py
+++ b/cartridge/shop/views.py
@@ -192,7 +192,8 @@ def checkout_steps(request):
             sensitive_card_fields = ("card_number", "card_expiry_month",
                                      "card_expiry_year", "card_ccv")
             for field in sensitive_card_fields:
-                del request.session["order"][field]
+                if field in request.session["order"]:
+                    del request.session["order"][field]
 
             # FIRST CHECKOUT STEP - handle shipping and discount code.
             if step == checkout.CHECKOUT_STEP_FIRST:

F object batch update of Priced objects by Sale fails on mysql

Warning at /admin/shop/sale/2/

Data truncated for column 'sale_price_aud' at row 59

in shop/models.py: Sale.save:
for priced_objects in (products, variations):
priced_objects.filter(**extra_filter).update(sale_id=self.id,
sale_to=self.valid_to, sale_from=self.valid_from,
sale_price=sale_price)

PDF invoice is missing czech characters

when i generate PDF, non-latin1 characters are displayed as black boxes. Not yet sure why.

virtualenv package versions are:

Cartridge==0.8.4
Django==1.5.5
Mezzanine==1.4.16
Pillow==2.2.1
argparse==1.2.1
bleach==1.2.2
distribute==0.6.24
filebrowser-safe==0.2.31
grappelli-safe==0.2.23
html5lib==0.95
ipython==1.1.0
oauthlib==0.6.0
pisa==3.0.33
pyPdf==1.13
pytz==2013.8
reportlab==2.7
requests==1.2.3
requests-oauthlib==0.3.3
wsgiref==0.1.2

Checkout form populates discount code from previous order rather than session

Assume a user has entered a discount code in their cart.

When they go to the checkout, the discount code form field (under the address info) is populated with the discount code used in their previous order, and not with the discount code from the session.

I also believe that the discount code field should /never/ be populated from a previous order, even when that code is still valid.

Small modification to OrderForm.init():

if initial is not None:
    initial["step"] = step
    code = request.session.get('discount_code', None)
    initial["discount_code"] = code

url.py configuration.

Hi,

I hope you don't mind newbie questions. I am trying to set up and configure the main url to be the shop page. I checked out the code and saw that category.html was use as a page template. I am not sure what points to it. And I see the blog example from Mezzanine in the url.py to point to blog. I tired similar setting for the url for shop but I still could not get it right. Is there an example I can look at to do that simple setting? How could I set shop link to be the main home page and blog link to be secondary link? Thank you for your help.

Watt Poosanguansit

conflict with mezzanine multi-tenancy?

I am not entirely sure if this is a bug in mezzanine or cartridge, but either way I am running out of PEBKAC to blame (I think!).

Scenario:

A single mezzanine project with two sites, foo.local and bar.local. bar.local is a CNAME for foo.local. Both hosts served via nginx/uwsgi.

Repro Steps:

  1. deploy fresh project
  2. visit foo.local/admin, log in, create a new site 'bar.local'
  3. select 'bar.local' in the drop down and add a product, 'product1'.

Expected Result:

Visiting http://bar.local/shop/product/product1 should display the product page, while http://foo.local/shop/product/product1 should return a 404.

Actual Result:

The product page is visible at both URLs.

Workaround Steps:

  1. deploy fresh project
  2. visit foo.local/admin, log in, create a new site 'bar.local'
  3. visit bar.local/admin, log in
  4. select 'bar.local' in the drop down and add a product, 'product1'.

Following these steps yields the expected result, that is, the product page is only visible on the host bar.local.

pip freeze:

Cartridge==0.8.4
Django==1.5.4
Mezzanine==1.4.16
MySQL-python==1.2.4
Pillow==2.2.1
argparse==1.2.1
bleach==1.2.2
django-appconf==0.6
django-compressor==1.3
filebrowser-safe==0.2.31
grappelli-safe==0.2.22
html5lib==0.95
oauthlib==0.6.0
pisa==3.0.33
python-memcached==1.53
pytz==2013.7
requests==1.2.3
requests-oauthlib==0.3.3
setproctitle==1.1.7
six==1.4.1
wsgiref==0.1.2

Support strictly hierarchical product views and URLs

Hi Stephen,

I'd like to support a strict hierarchy of products. Perhaps an illustration of the desired outcome will explain best.

Here's what the store's left nav and URLs would ideally look like:

My Store                           /store/
  |- Hardware (category)           /store/hardware/
      |--- Product 1               /store/hardware/product-1/
      |--- Product 2               /store/hardware/product-2/
  |- Accessories                   /store/accessories/
      |--- Product 3               /store/accessories/product-3/
      |--- Product 4               /store/accessories/product-4/

On each product page, I'd like to render the nav bar and breadcrumbs in terms of each product's one (and only) category, ie:

[Home] / [My Store] / [Hardware] / Product 1

Today each product has a ManyToMany relationship to zero or more Categories. I see two ways to support this:

Option 1

Modify Product.get_absolute_url() to inspect Product.categories to find the Product's canonical category.

When len(self.categories) == 1, return a different view mapped to the URL /<category_slug>/<slug>/ instead of /product/<slug>/.

Pro:

  • No change to existing models.
  • Backwards compatible.

Con:

  • Extra DB lookups (joins against M2M table, I guess) for get_absolute_url() and product view.

Option 2

Add a new field to Product indicating the "primary" category:

    primary_category = models.ForeignKey("Category", _("Primary category"),
            blank=True, null=True, on_delete=models.SET_NULL)

Pro:

  • Explicit, avoids M2M lookup in get_absolute_url.

Con:

  • Creates a Product -> Category dependency, a circular relationship (due to Category -> Products).

Perhaps you have other ideas. I am leaning towards option 1; it could be gated by a feature flag (default off) out of concern for extra DB load.

One other thought: A view serving /<category_slug>/<product_slug>/ should be forgiving in the event that category_slug does not match the product's category.

Since product_slug unambiguously identifies the product, the view should issue a 301 redirect to product.get_absolute_url(). This keeps hierarchical URLs while allowing categories to be renamed/changed in the future.

"value too long for type character varying(200)" when adding a Product to the shopping cart

I created completely localized website in russian, so everything is in russian including product names, product variations etc..

Wher adding a product to the shopping cart (with one variation, which is in russian too) I get the error (below).
And here the SQL statement (from PostgreSQL logs, below).
Probably the "url" field is too short, probably because of this translation Unicode->%D0%B8

The quick fix could be just increasing the field length.

Hint: may be such kilometer long urls make not so much sense... is there an easy way to install a custom "encoding" function?. I mean to translate the product name "Полоски вертикальные, полотенцесушитель" to url "poloski-vertikalnie-polotenzesushitel" (this is so called "translit", a special way to write in russian using latine alphabet, there are enough functions to do this translation, I'm asking about a possibility to plug-in such function into Cartridge. I want to edit products in Admin and get the urls in Latine/english automatically)

2013-06-03 01:07:20 EEST 0 LOG:  statement: BEGIN
2013-06-03 01:07:20 EEST 0 LOG:  duration: 0.049 ms
2013-06-03 01:07:20 EEST 0 LOG:  statement: SELECT (1) AS "a" FROM "shop_cartitem" WHERE "shop_cartitem"."id" = 57  LIMIT 1
2013-06-03 01:07:20 EEST 0 LOG:  duration: 0.187 ms
2013-06-03 01:07:20 EEST 0 LOG:  statement: UPDATE "shop_cartitem" SET "sku" = '96', "description" = 'Полоски вертикальные, полотенцесушитель 
Размер, мм: 500x600', "quantity" = 1, "unit_price" = '1900.00', "total_price" = '1900.00', "cart_id" = 38, "url" = '/shop/product/%D0%BF%D0%BE
%D0%BB%D0%BE%D1%81%D0%BA%D0%B8-%D0%B2%D0%B5%D1%80%D1%82%D0%B8%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE%D0%BB%D0%BE%D1%82%D0%B5%D
0%BD%D1%86%D0%B5%D1%81%D1%83%D1%88%D0%B8%D1%82%D0%B5%D0%BB%D1%8C/', "image" = 'product/DSC02493.jpg' WHERE "shop_cartitem"."id" = 57 
2013-06-03 01:07:20 EEST 0 ERROR:  value too long for type character varying(200)
2013-06-03 01:07:20 EEST 0 STATEMENT:  UPDATE "shop_cartitem" SET "sku" = '96', "description" = 'Полоски вертикальные, полотенцесушитель Разме
р, мм: 500x600', "quantity" = 1, "unit_price" = '1900.00', "total_price" = '1900.00', "cart_id" = 38, "url" = '/shop/product/%D0%BF%D0%BE%D0%B
B%D0%BE%D1%81%D0%BA%D0%B8-%D0%B2%D0%B5%D1%80%D1%82%D0%B8%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE%D0%BB%D0%BE%D1%82%D0%B5%D0%BD%
D1%86%D0%B5%D1%81%D1%83%D1%88%D0%B8%D1%82%D0%B5%D0%BB%D1%8C/', "image" = 'product/DSC02493.jpg' WHERE "shop_cartitem"."id" = 57 
2013-06-03 01:07:20 EEST 0 LOG:  statement: ROLLBACK
Environment:


Request Method: POST
Request URL: http://localhost:8000/shop/product/%D0%BF%D0%BE%D0%BB%D0%BE%D1%81%D0%BA%D0%B8-%D0%B2%D0%B5%D1%80%D1%82%D0%B8%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE%D0%BB%D0%BE%D1%82%D0%B5%D0%BD%D1%86%D0%B5%D1%81%D1%83%D1%88%D0%B8%D1%82%D0%B5%D0%BB%D1%8C/

Django Version: 1.5.1
Python Version: 2.7.3
Installed Applications:
('mezzanine.boot',
 'theme1',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.redirects',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.sitemaps',
 'django.contrib.staticfiles',
 'cartridge.shop',
 'mezzanine.conf',
 'mezzanine.core',
 'mezzanine.generic',
 'mezzanine.blog',
 'mezzanine.forms',
 'mezzanine.pages',
 'mezzanine.galleries',
 'mezzanine.accounts',
 'filebrowser_safe',
 'grappelli_safe',
 'django.contrib.admin',
 'django.contrib.comments')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.redirects.middleware.RedirectFallbackMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'cartridge.shop.middleware.ShopMiddleware',
 'mezzanine.core.request.CurrentRequestMiddleware',
 'mezzanine.core.middleware.TemplateForDeviceMiddleware',
 'mezzanine.core.middleware.TemplateForHostMiddleware',
 'mezzanine.core.middleware.AdminLoginInterfaceSelectorMiddleware',
 'mezzanine.core.middleware.SitePermissionMiddleware',
 'mezzanine.pages.middleware.PageMiddleware')


Traceback:
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  109.                         response = middleware_method(request, callback, callback_args, callback_kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/mezzanine/pages/middleware.py" in process_view
  71.             response = view_func(request, *view_args, **view_kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/cartridge/shop/views.py" in product
  58.                 request.cart.add_item(add_product_form.variation, quantity)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/cartridge/shop/utils.py" in add_item
  47.         cart.add_item(*args, **kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/cartridge/shop/models.py" in add_item
  555.         item.save()
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/cartridge/shop/models.py" in save
  638.             super(SelectedProduct, self).save(*args, **kwargs)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/db/models/base.py" in save
  546.                        force_update=force_update, update_fields=update_fields)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/db/models/base.py" in save_base
  626.                             rows = manager.using(using).filter(pk=pk_val)._update(values)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/db/models/query.py" in _update
  591.         return query.get_compiler(self.db).execute_sql(None)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1014.         cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  840.         cursor.execute(sql, params)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/db/backends/util.py" in execute
  41.             return self.cursor.execute(sql, params)
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py" in execute
  58.             six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
File "/home/dima/.virtualenvs/prj_inox/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py" in execute
  54.             return self.cursor.execute(query, args)

Exception Type: DatabaseError at /shop/product/полоски-вертикальные-полотенцесушитель/
Exception Value: value too long for type character varying(200)

Markdown doesn't work on Product content

shop/product.html lacks the richtext_filter tag, so markdown doesn't get rendered as it should be.

Change from:
{{ product.content|safe }}
to:
{{ product.content|richtext_filter|safe }}

Draft products show up as coming soon

Is this the intended functionality? If not, it is an easy enough fix I can submit it in no-time.

However, my shop has three hundred thousand (300,000) different products, of which only 6,000 are available at a given time. This means that the user has to wade through hundreds of thousands of products to find ones that they can even buy.

I can submit a patch to dynamically specify the behavior based on a setting, as an alternative.

Working on this right now...

no reverse match at /shop/checkout/

I noticed that if you set SHOP_CHECKOUT_ACCOUNT_REQUIRED to True in your settings you get a no reverse match at /shop/checkout/. This can be fixed by changing reverse("shop_CHECKOUT") to reverse("shop_checkout") on line 216 of cartridge.shop.views.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.