Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Apress committed Oct 13, 2016
0 parents commit b75d01f
Show file tree
Hide file tree
Showing 823 changed files with 228,558 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.swp
*.pyc
settings_local.py
.pydevproject
.project
src/
26 changes: 26 additions & 0 deletions Beginning_Django_Ecommerce_source/Chapter_01-15/ecomstore/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
MIT License
-----------

Copyright (c) 2009 Apress and Jim McGaw

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

54 changes: 54 additions & 0 deletions Beginning_Django_Ecommerce_source/Chapter_01-15/ecomstore/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
The source for this e-commerce project is code for the Apress book "Beginning Django E-Commerce" by Jim McGaw ( jim@django-ecommerce.com )

Add the project to your system's PYTHONPATH
-------------------------------------------
Make sure that the ecomstore directory where you put your project on your machine is on your system's PYTHONPATH.


Prepare the MySQL database
--------------------------
First, create a new database login with password, the database, and give the new login permissions to manipulate the site by running the following using the 'root' MySQL user on your local machine:

mysql> CREATE USER 'login'@'localhost' IDENTIFIED BY 'password';
mysql> CREATE DATABASE ecomstore CHARACTER SET utf8;
mysql> GRANT ALL ON ecomstore.* TO 'login'@'localhost';

Once you have done this, update the database settings in your settings.py file to match the values you used above. Then, run the following from inside the root of your project:

$ python manage.py validate

If no errors are found, then run:

$ python manage.py syncdb

If you're interested in loading test data (Modern Musician product catalog featured in the book), run the following to load the sample data:

$ python manage.py loaddata catalog


Other Requirements
------------------

Installation of the Django E-Commerce store requires the following additional applications to be installed:

Django-Tagging
URL: http://code.google.com/p/django-tagging/
Instructions: After downloading the project files above, put the 'tagging' directory onto your system's PYTHONPATH

Django DB Log
URL: http://github.com/dcramer/django-db-log
Instructions: Put the 'djangodblog' directory onto your system's PYTHONPATH

Google Keyczar
URL: http://code.google.com/p/keyczar/
Instructions: Make sure to download the Python version of the keyczar library.
Put the 'src/keyczar' directory onto your system's PYTHONPATH

In order to use the CACHE_BACKEND in settings.py, you need to also install a Memcached server on your local development machine.
URL: http://www.danga.com/memcached/
Instructions: Install per the documentation for your operating system. After doing so, uncomment and (if necessary) update the
CACHE_BACKEND value in settings.py.

Before using, be sure to generate a long random string of characters for the SECRET_KEY value in settings.py.

For questions or comments about this project contact Jim at: jim@django-ecommerce.com.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
__license__ = "Python"
__copyright__ = "Copyright (C) 2007, Stephen Zabel"
__author__ = "Stephen Zabel - sjzabel@gmail.com"
__contributors__ = "Jay Parlar - parlar@gmail.com"

from django.conf import settings
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect, get_host

SSL = 'SSL'

class SSLRedirect:
""" middleware class for handling redirects back and forth between secure and non-secure pages.
Taken from: http://www.djangosnippets.org/snippets/880/
"""
def process_view(self, request, view_func, view_args, view_kwargs):
if SSL in view_kwargs:
secure = view_kwargs[SSL]
del view_kwargs[SSL]
else:
secure = False

if not secure == self._is_secure(request):
return self._redirect(request, secure)

def _is_secure(self, request):
if request.is_secure():
return True

#Handle the Webfaction case until this gets resolved in the request.is_secure()
if 'HTTP_X_FORWARDED_SSL' in request.META:
return request.META['HTTP_X_FORWARDED_SSL'] == 'on'

return False

def _redirect(self, request, secure):
protocol = secure and "https" or "http"
newurl = "%s://%s%s" % (protocol,get_host(request),request.get_full_path())
if settings.DEBUG and request.method == 'POST':
raise RuntimeError, \
"""Django can't perform a SSL redirect while maintaining POST data.
Please structure your views so that redirects only occur during GETs."""

return HttpResponsePermanentRedirect(newurl)
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"pk": 12,
"model": "auth.user",
"fields": {
"username": "alice",
"first_name": "",
"last_name": "",
"is_active": 1,
"is_superuser": 0,
"is_staff": 0,
"last_login": "2009-07-05 16:23:11",
"groups": [],
"user_permissions": [],
"password": "sha1$c7480$27c375944e52bfaf36b19153011a68e2afc9a9c7",
"email": "jim@django-ecommerce.com",
"date_joined": "2009-05-25 20:12:04"
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django import forms
from django.contrib.auth.forms import UserCreationForm
from ecomstore.accounts.models import UserProfile

class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
exclude = ('user',)

class RegistrationForm(UserCreationForm):
""" subclass of Django's UserCreationForm, to handle customer registration with a required minimum length
and password strength. Also contains an additional field for capturing the email on registration.
"""
password1 = forms.RegexField(label="Password", regex=r'^(?=.*\W+).*$',
help_text='Password must be six characters long and contain at least one non-alphanumeric character.',
widget=forms.PasswordInput, min_length=6)
password2 = forms.RegexField(label="Password confirmation", regex=r'^(?=.*\W+).*$',
widget=forms.PasswordInput, min_length=6)
email = forms.EmailField(max_length="50")
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.db import models
from django.contrib.auth.models import User
from ecomstore.checkout.models import BaseOrderInfo

class UserProfile(BaseOrderInfo):
""" stores customer order information used with the last order placed; can be attached to the checkout order form
as a convenience to registered customers who have placed an order in the past.
"""
user = models.ForeignKey(User, unique=True)

def __unicode__(self):
return 'User Profile for: ' + self.user.username
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from ecomstore.accounts.models import UserProfile
from ecomstore.accounts.forms import UserProfileForm

def retrieve(request):
""" gets the UserProfile instance for a user, creates one if it does not exist """
try:
profile = request.user.get_profile()
except UserProfile.DoesNotExist:
profile = UserProfile(user=request.user)
profile.save()
return profile

def set(request):
""" updates the information stored in the user's profile """
profile = retrieve(request)
profile_form = UserProfileForm(request.POST, instance=profile)
profile_form.save()

Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from django.test import TestCase, Client
from django.contrib.auth.models import User
from django.core import urlresolvers

from ecomstore.catalog.models import Product
from ecomstore.checkout.models import Order, OrderItem
from ecomstore import settings

import httplib

TEST_USERNAME = "alice"
TEST_PASSWORD = "test"

class OrderHistoryTestCase(TestCase):
def setUp(self):
self.client = Client()
logged_in = self.client.login(username=TEST_USERNAME, password=TEST_PASSWORD)
self.failUnless(logged_in)
self.user = User.objects.get(username=TEST_USERNAME)
self.failUnless(self.user)

def test_browse_order_history(self):
""" customer can view the details of their own past orders """
my_account_url = urlresolvers.reverse('my_account')
response = self.client.get(my_account_url)
self.failUnlessEqual(response.status_code, httplib.OK)
order = Order.objects.filter(user=self.user)[0]
self.assertContains(response, unicode(order))

order_url = order.get_absolute_url()
response = self.client.get(order_url)
self.failUnlessEqual(response.status_code, httplib.OK)
products = Product.objects.filter(orderitem__order=order)
for p in products:
self.assertContains(response, unicode(p))

class LoginTestCase(TestCase):
""" test customer login """
def setUp(self):
self.client = Client()
self.login_url = urlresolvers.reverse('login')
self.login_data = {"username": TEST_USERNAME, "password": TEST_PASSWORD}

def test_user_login(self):
response = self.client.post(self.login_url, self.login_data)
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)

def test_user_login_redirect(self):
""" if URL contains 'next' parameter, customer is redirected after successfully logging in """
my_account_url = urlresolvers.reverse('my_account')
redirect_url = self.login_url + '?next=' + my_account_url

response = self.client.get(my_account_url)
self.assertRedirects(response, redirect_url,
status_code=httplib.FOUND, target_status_code=httplib.OK)

response = self.client.post(redirect_url, self.login_data)
self.assertRedirects(response, my_account_url,
status_code=httplib.FOUND, target_status_code=httplib.OK)

class RegistrationTestCase(TestCase):
def setUp(self):
self.client = Client()
self.register_url = urlresolvers.reverse('register')

def test_user_registration(self):
pass

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from django.conf.urls.defaults import *
from ecomstore import settings

urlpatterns = patterns('ecomstore.accounts.views',
(r'^register/$', 'register',
{'template_name': 'registration/register.html', 'SSL': settings.ENABLE_SSL }, 'register'),
(r'^my_account/$', 'my_account',
{'template_name': 'registration/my_account.html'}, 'my_account'),
(r'^order_info/$', 'order_info',
{'template_name': 'registration/order_info.html'}, 'order_info'),
(r'^order_details/(?P<order_id>[-\w]+)/$', 'order_details',
{'template_name': 'registration/order_details.html'}, 'order_details'),
)

urlpatterns += patterns('django.contrib.auth.views',
(r'^login/$', 'login',
{'template_name': 'registration/login.html', 'SSL': settings.ENABLE_SSL }, 'login'),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.template import RequestContext
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.core import urlresolvers
from django.http import HttpResponseRedirect

from ecomstore.checkout.models import Order, OrderItem
from ecomstore.accounts.forms import UserProfileForm, RegistrationForm
from ecomstore.accounts import profile

def register(request, template_name="registration/register.html"):
""" view displaying customer registration form """
if request.method == 'POST':
postdata = request.POST.copy()
form = RegistrationForm(postdata)
if form.is_valid():
#form.save()
user = form.save(commit=False) # new
user.email = postdata.get('email','') # new
user.save() # new
un = postdata.get('username','')
pw = postdata.get('password1','')
from django.contrib.auth import login, authenticate
new_user = authenticate(username=un, password=pw)
if new_user and new_user.is_active:
login(request, new_user)
url = urlresolvers.reverse('my_account')
return HttpResponseRedirect(url)
else:
form = RegistrationForm()
page_title = 'User Registration'
return render_to_response(template_name, locals(), context_instance=RequestContext(request))

@login_required
def my_account(request, template_name="registration/my_account.html"):
""" page displaying customer account information, past order list and account options """
page_title = 'My Account'
orders = Order.objects.filter(user=request.user)
name = request.user.username
return render_to_response(template_name, locals(), context_instance=RequestContext(request))

@login_required
def order_details(request, order_id, template_name="registration/order_details.html"):
""" displays the details of a past customer order; order details can only be loaded by the same
user to whom the order instance belongs.
"""
order = get_object_or_404(Order, id=order_id, user=request.user)
page_title = 'Order Details for Order #' + order_id
order_items = OrderItem.objects.filter(order=order)
return render_to_response(template_name, locals(), context_instance=RequestContext(request))

@login_required
def order_info(request, template_name="registration/order_info.html"):
""" page containing a form that allows a customer to edit their billing and shipping information that
will be displayed in the order form next time they are logged in and go to check out """
if request.method == 'POST':
postdata = request.POST.copy()
form = UserProfileForm(postdata)
if form.is_valid():
profile.set(request)
url = urlresolvers.reverse('my_account')
return HttpResponseRedirect(url)
else:
user_profile = profile.retrieve(request)
form = UserProfileForm(instance=user_profile)
page_title = 'Edit Order Information'
return render_to_response(template_name, locals(), context_instance=RequestContext(request))



Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This directory should contain a file named 'django.wsgi', which is for integrating this Django project with an Apache web server.

Provided that your project is being hosted in a Unix/Linux server, you can use the VirtualHost found in the 'apache_virtual_host.txt' file in order to deploy your project. Note that you will need to change some of the values below in order to match those of your server machine, as well as hostname.

0 comments on commit b75d01f

Please sign in to comment.