awesto / django-shop Goto Github PK
View Code? Open in Web Editor NEWA Django based shop system
Home Page: http://www.django-shop.org
License: BSD 3-Clause "New" or "Revised" License
A Django based shop system
Home Page: http://www.django-shop.org
License: BSD 3-Clause "New" or "Revised" License
it seems we use these two constants for the same thing:
SHOP_CART_MODIFIERS
SHOP_PRICE_MODIFIERS
While already a major improvement, the show_cart templatetag should display more information about the cart, closer to something like:
https://github.com/divio/django-shop/blob/master/shop/templates/shop/cart.html
It might also be interesting to have a show_cart_info tag to show the number of items in the cart and maybe the cart's total
When you checkout, your basket is still full with w/e you bought. It should be emptied to reflect that the purchase was succesfull.
shop/urls.py needs the addition of ;
url('^cart/item/(?P<id>[0-9A-Za-z-_.//]+)/delete$', CartItemDetail.as_view(action='delete'),
name='cart_item_delete' ),
Guys, i have some problem with configuring django-shop app
i set SHOP_CART_MODEL to 'apps.carts.models.MyCart'
and try two ways:
MyCart model based on Cart (like in docs on http://readthedocs.org/docs/django-shop/en/latest/howto/how-to-extend-django-shop-models.html
from shop.models import Cart
class MyCart(Cart):
class Meta(object):
pass
this raise:
django.core.exceptions.ImproperlyConfigured: Error importing backend apps.carts.models: "cannot import name Cart". Check your SHOP_CART_MODEL setting
and MyCart model based on BaseCart
from shop.models.defaults.bases import Cart
class MyCart(Cart):
class Meta(object):
pass
it raise:
django.core.exceptions.ImproperlyConfigured: Backend module "apps.carts.models" does not define a "MyCart" class.
it takes me much time of trying to fix it. guys, please, help)
as discussed on irc
product_reference in OrderItem should allow keeping product SKU (IAN, EAN, UPC) code of product when order has completed.
see: http://en.wikipedia.org/wiki/Stock-keeping_unit
default Product.get_product_reference() implementation should be product pk.
right?
The order of stuff on the Models is all wrong:
http://docs.djangoproject.com/en/1.2/internals/contributing/#model-style
I am trying to use customized cart model by subclassing shop.models.defaults.bases.BaseCart and setting SHOP_CART_MODEL in settings. Afterwards I get following traceback (https://gist.github.com/1200507) that suggests the problem is caused by circular imports in shop.util.loader module. What would be the best way to tackle this โ separate BaseCart and BaseCartItem to different files, hack shop.util.get_model_string not to use load_class(), or is there another way?
Hi, few things regarding product model:
what do you think?
For examle i have cocaine store selling cocaine online.
customers what to buy 1.125 kg of cocaine, but quantity is integer, so customers can buy only 1 or 2 kg.
you should probably make it float\double.
This may not seem like a bad thing now, but it becomes a problem if you ever want to do analysis on that data ( see airtonix/cmsplugin-shop#1 ).
Is there any reason why this would not be a ForeignKey with on_delete=[NULL|PROTECT] ? This would allow ORM querying as expected and also preserve OrderItems when Products are deleted.
I would be happy to submit patches/tests if needed.
I try to make it with django-hvad, but is going very dificult because of inheritance on PolymorphicModel, my question is what should we use for model translations in django-shop?
If we delete Cart object instead of calling empty on it, one can easily register to delete signal.
what do you think?
During normal usage, the shop creates instances of different models that are not used anymore at a later state. This should be documented, and methods to clean up these orphaned instances should be provided.
A (quite possibly not complete) list of such "garbage"
Cart
inclusion tag get_or_create
s a cart every time it is accessed, e.g. when Google crawles the site or somobody's just (literally) browsing *.CheckoutSelectionView
creates an Order
instance. If the user abandons the checkout process somewhere before reaching the ThankYouView
, this instance can be deleted after some time.CheckoutSelectionView
creates Address
instances which, at least for anonymous users, have no relation with other models, which basically makes them garbage after being serialized into the Order
instance.It's probably not a good idea to just delete this "garbage", since it may very well be perceived as valuable data, depending on the scenario. Instead, we should document these cases, and perhaps provide exemplary management commands and/or celery PeriodicTask
s to clean them up.
Cart
inclusion tag, it would perhaps make sense to create the cart lazily when the first item is added to it. Different issue, though.I want to be able to replace default models from personalized ones.
For exemple, If I define a proxy Cart which overrides the add_to_product method for adding stock control, I want to replace the default Cart model in django-shop with my proxy model.
The best way to do that, in my point of view is to define models in settings or a dependency injection layer which can be overrided by users.
item_quantity does not get validated allowing to post negative or non-numeric quantity
https://github.com/divio/django-shop/blob/master/shop/views/cart.py#L51
I am not sure what the best approach for this would be.
a) We just add an errors dict to the context. We could at least place a warning on top of the cart.
If we want to show the error next to the field that has the wrong value, things will get complicated.
b) We generate a form dynamically from the request. The form will search for the ids of the cart items and for each id it will add a form field that only accepts positive integers and zero. Problem: Obviously we cannot use {{ form.as_p }} but we would want to use {{ form.fieldname.errors }}. But how do we know the fieldname in the template? It is dynamic as well. We would probably need a templatetag that accepts the form and the id of the cart item and spit out the rendered error... oh wee...
Backends (or the shop's API, even better) should check for an entry's presence before adding ExtraOrderPriceFields.
Steps to reproduce:
I meet some use cases and it seems impossible to achieve without a way to put more data in extra price fields:
1 Tax grouping
Using per item tax modifier (ie: TenPercentPerItemTaxModifier) and want to display summary for each Tax at the end of cart, ie:
VAT 20%, Base = 12,00 EUR, Tax = 2,00 EUR
VAT 8,50%, Base = 10,85 EUR, Tax = 0,85 EUR
2 Hiding some cart fields
On every page, one may want to display cart, but do not want to overfill space with Tax fields for every item.
3 Tax for shipping
One could want to have Tax information to exists for shipping in ExtraOrderPriceField
For 1. and 2. cases I think it would be easily achieved with adding optional group
(or groups
) string attribute to already existing label
and amount
fields. This change should be backward compatible.
For third case, I am not sure if it would be enough to assign tax label to group
and handle it in custom code.
What do you think?
When cart_object is updated, it loops through cart items calling update
on them, but
cart items data is immediately forgotten
Meaning that for displaying cart content, cart_item.update() is called twice for every cart item. Example is in cart display view code:
https://github.com/divio/django-shop/blob/master/shop/views/cart.py#L106-115
What do you think?
it calls a bunch of methods that does not exists anymore.
should it call confirm_payment and return render success template?
When seeing the cart, you can just enter /ship/flat/ as a URL and click at the submit button. This will obviously result in the following error:
ValueError at /shop/ship/flat/process/
Cannot assign None: "ExtraOrderPriceField.order" does not allow null values.
How do we handle this? Does the shop need to be aware of the current step and redirect to that step in case someone manipulates the URL?
For this to happen we need to assert that most common usecases are covered by the shop API, both for the payment backends and for the shipping backends.
it would be nice to know city of customer :)
If there is no user connected to Order, or the user is not logged in, payment api would raise an exception.
bug is introduced in 13ddf80
see:
13ddf80#L0R55
if I remember correclty, every backend should have url_namespace prepended in payment urls:
https://github.com/divio/django-shop/blob/master/shop/payment/urls.py#L19
Hello!
First of all, excellent piece of code! Really straightforward and easy to integrate in existing projects contrary to all other shop modules I've tried.
I'm trying to have the "active" field of the "Product" class set to True by default but I cannot find a way to do this from my child class in models.py. Any suggestions?
If you change shipping price through admin order total price did not changed, so need to recount in manually.
I believe we need to add something like this in BaseOrder:
def save(self, force_insert=False, force_update=False, using=None):
self.order_subtotal = Decimal(0.00)
for item in self.items.all():
self.order_subtotal += item.line_total
self.order_total = self.order_subtotal
for i in self.extraorderpricefield_set.all():
self.order_total += i.value
return super(BaseOrder, self).save(force_insert, force_update, using)
PS i'm new in git, so tell me please, if i have some useful code, i should not paste it in issue, just make a pull requests ? Thank you.
When payment backend process and order, it should change status of the order, ie in:
https://github.com/divio/django-shop/blob/master/shop/payment/backends/pay_on_delivery.py#L28
Order status should be Order.completed
, right?
The current templates do not reflect the ManyToMany model between categories and products.
Is there an other way to submit patches, rather than Email?
diff --git a/shop/templates/shop/product_detail.html b/shop/templates/shop/product_detail.html
index 70d4ade..323b061 100644
--- a/shop/templates/shop/product_detail.html
+++ b/shop/templates/shop/product_detail.html
@@ -10,8 +10,8 @@
{{object.unit_price}}
-{% if object.category %}
-{{object.category.name}}
+{% if object.categories %}
+{% for cat in object.categories.all %} {{ cat.name }} {% endfor %}
{% else %}
(Product is at root category)
{% endif %}
diff --git a/shop/templates/shop/product_list.html b/shop/templates/shop/product_list.html
index c7314c0..6439c39 100644
--- a/shop/templates/shop/product_list.html
+++ b/shop/templates/shop/product_list.html
@@ -13,8 +13,8 @@
{{object.unit_price}}
-{% if object.category %}
-{{object.category.name}}
+{% if object.categories %}
+{% for cat in object.categories.all %} {{ cat.name }}
{% endfor %}
{% else %}
(Product is at root category)
{% endif %}
To let people get creative with django-SHOP on the template fronts, we should add some mechanism to let them display orders easily.
Since this will be django-SHOP specific, it should go in-tree, and not in a plugin.
I've ran into this bug while trying to run tests (http://stackoverflow.com/questions/10058277/django-test-fails-when-creating-test-database/) and a user of one of my plugins has ran into it when running my migrations: Lacrymology/django-shop-area-tax#1
The issue seems to be the existence of two models with ForeignKey(User, related_name="[shipping|billing]_address"..)
, i.e.: your own user-defined models and shop.addressmodel.Address
.
Even if you don't add shop.addressmodel
to your user models, the tests import them to use them, and then conflict arises, in the case of the bug the other user is reporting, I'm not sure where the import's coming from.
But it has lead me to think that my own app will have the same problem, if a user wants to use the l10n app, but wants to provide their own Address model. I think I'll have to move it out of my app's models.py file, that'd do the trick, wouldn't it?
$ pip install -e git+https://github.com/divio/django-shop.git#egg=djangoshop
Obtaining djangoshop from git+https://github.com/divio/django-shop.git#egg=djangoshop
Cloning https://github.com/divio/django-shop.git to /Users/issackelly/virtualenvs/djangoshop/src/djangoshop
Running setup.py egg_info for package djangoshop
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/Users/issackelly/virtualenvs/djangoshop/src/djangoshop/setup.py", line 12, in <module>
long_description=open(os.path.join(os.path.dirname(__file__), 'README.rst')).read(),
NameError: name 'os' is not defined
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/Users/issackelly/virtualenvs/djangoshop/src/djangoshop/setup.py", line 12, in <module>
long_description=open(os.path.join(os.path.dirname(__file__), 'README.rst')).read(),
NameError: name 'os' is not defined
I am using the example shipping and payment backends. Whenever I proceed to checkout, I see the address forms displayed correctly, but the Payment and Shipping select widgets do not get rendered by the template at all. Looking at get_billing_and_shipping_selection_form() in shop.views.checkout.CheckoutSelectionView, at line 134 has the following assignment:
form = BillingShippingForm
which I believe should be:
form = BillingShippingForm()
When I substitute, it works.
The "thank you" page is displayed through a GET request, so loading it multiple times should have no side effects, but it does. The most problematic one being the "completed" signal being sent again if a user reloads the thank you page.
I don't see how we could do this stuff (sending the signal, changing the status of the order, clearing the cart) in a POST request without breaking the current flow of the checkout process. The best I could come up with was to check if the order is already marked as completed:
def get_context_data(self, **kwargs):
ctx = super(ShopTemplateView, self).get_context_data(**kwargs)
# Set the order status:
order = get_order_from_request(self.request)
if order and order.status != Order.COMPLETED:
order.status = Order.COMPLETED
order.save()
completed.send(sender=self, order=order)
cause get_billing_form_class make no sense
The method name shop.payment.api.PaymentAPI.get_finished_url
(and its sibling get_cancel_url
) implies that the method will return an URL (similar to get_absolute_url
of django models), but they return a response.
To make the API more intuitive, I propose to do one of the following:
get_finished_response
)In that method there's a line
i.product_reference = item.id
Which is wrong, because i is the instance of CartItem and you really need to do
i.product_reference = item.product.id
to reference the product.
See 82ef773#commitcomment-903931 for details
In both cart and order modifiers, there should be a way to make the label part display in a multilingual fashion. Right now, using gettext works, but the result of the gettext call gets saved in the database.
Therefore another user seeing the same order will see the label as translated in the original language.
It would make more sense to let the implementor decide what the behavior of the "add to cart" button click should have:
Maybe a setting is the beginning of the end (settingitis!!), but it seems reasonable here... Maybe a sensible default is a good idea, so as to make the setting, in effect, optional?
I'm using djangoshop inside djangocms, via a cmsplugin, cmsapp and cmsmenu.
now the problem is that because shop.urls are no longer in my projects url conf (and instead handled by the menu and cmsapp), redirects in the CartDetails and CartItemDetails (or anywhere else you hardcode redirect urlconf names) fail to resolve since my shop application has it's urls namespaced.
By allowing CartDetails.as_view to accept a kwarg like success_redirect='theshop:cart', we can make using djangoshop as a cmsplugin easier.
I do want to use namespaces in my urlconf and If I am missing an obvious way to override this without modifying the code, let me know.
First product name is set:
https://github.com/divio/django-shop/blob/master/shop/models/defaults/managers.py#L109
then it is re-set:
https://github.com/divio/django-shop/blob/master/shop/models/defaults/bases.py#L424
it would be nice to have statuses for orders like DELIVERED, CANCELED etc.
While the save() override is not really a best proactice, this allows for Product subtypes not to have to register themselves. We need to document this better.
Also, specify() should be called get_specific() to implicitly let people know now to chain the call
Finally, the save() method should avoid overriding the subtype field when saving a Product
product FK should be nullable (Django 1.2 compatibility)
I am adding my shipping costs like so:
def add_extra_cart_price_field(self, cart):
cart.extra_price_fields.append(
(_('Shipping costs'),
decimal.Decimal(settings.SHOP_SHIPPING_FLAT_RATE)))
return cart
When I place an order and look at that order in the order admin, the label field looks like this:
<django.utils.functional.proxy object at 0xb243d0c>
Is there a simple way to fix this??
The documentation is now mostly a set of Howtos. While it does solve many problems and is already a good start, the documentation should also be written in prosa, and include things like installation, getting started, "my first shop", etc...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.