upgrade to latest django (bug 612467)
This commit is contained in:
Родитель
591cbef8df
Коммит
c0ccbef35c
|
@ -205,7 +205,7 @@ class Addon(amo.models.ModelBase):
|
|||
related_name='addons')
|
||||
|
||||
_current_version = models.ForeignKey(Version, related_name='___ignore',
|
||||
db_column='current_version', null=True)
|
||||
db_column='current_version', null=True, on_delete=models.SET_NULL)
|
||||
|
||||
# This gets overwritten in the transformer.
|
||||
share_counts = collections.defaultdict(int)
|
||||
|
|
|
@ -39,6 +39,31 @@ def skip_cache():
|
|||
_locals.skip_cache = old
|
||||
|
||||
|
||||
# This is sadly a copy and paste of annotate to get around this
|
||||
# ticket http://code.djangoproject.com/ticket/14707
|
||||
def annotate(self, *args, **kwargs):
|
||||
|
||||
for arg in args:
|
||||
if arg.default_alias in kwargs:
|
||||
raise ValueError("The %s named annotation conflicts with the "
|
||||
"default name for another annotation."
|
||||
% arg.default_alias)
|
||||
kwargs[arg.default_alias] = arg
|
||||
|
||||
obj = self._clone()
|
||||
|
||||
obj._setup_aggregate_query(kwargs.keys())
|
||||
|
||||
# Add the aggregates to the query
|
||||
for (alias, aggregate_expr) in kwargs.items():
|
||||
obj.query.add_aggregate(aggregate_expr, self.model, alias,
|
||||
is_summary=False)
|
||||
|
||||
return obj
|
||||
|
||||
models.query.QuerySet.annotate = annotate
|
||||
|
||||
|
||||
class TransformQuerySet(queryset_transform.TransformQuerySet):
|
||||
|
||||
def pop_transforms(self):
|
||||
|
|
|
@ -137,7 +137,7 @@ class TestPaypal(test_utils.TestCase):
|
|||
@patch('amo.views.urllib2.urlopen')
|
||||
def test_not_verified(self, urlopen):
|
||||
urlopen.return_value = self.urlopener('xxx')
|
||||
response = self.client.post(self.url)
|
||||
response = self.client.post(self.url, {'foo': 'bar'})
|
||||
assert isinstance(response, http.HttpResponseForbidden)
|
||||
|
||||
@patch('amo.views.urllib2.urlopen')
|
||||
|
@ -194,7 +194,7 @@ class TestPaypal(test_utils.TestCase):
|
|||
@patch('amo.views.urllib2.urlopen')
|
||||
def test_any_exception(self, urlopen):
|
||||
urlopen.side_effect = Exception()
|
||||
response = self.client.post(self.url, {})
|
||||
response = self.client.post(self.url)
|
||||
eq_(response.status_code, 500)
|
||||
eq_(response.content, 'Unknown error.')
|
||||
|
||||
|
|
|
@ -209,39 +209,49 @@ def _paypal(request):
|
|||
if request.method != 'POST':
|
||||
return http.HttpResponseNotAllowed(['POST'])
|
||||
|
||||
if not request.META['CONTENT_LENGTH']:
|
||||
post = {}
|
||||
raw = ""
|
||||
else:
|
||||
# Copying request.POST to avoid this issue:
|
||||
# http://code.djangoproject.com/ticket/12522
|
||||
post = request.POST.copy()
|
||||
raw = request.raw_post_data
|
||||
|
||||
# Check that the request is valid and coming from PayPal.
|
||||
data = '%s&%s' % ('cmd=_notify-validate', request.raw_post_data)
|
||||
data = '%s&%s' % ('cmd=_notify-validate', raw)
|
||||
paypal_response = urllib2.urlopen(settings.PAYPAL_CGI_URL,
|
||||
data, 20).readline()
|
||||
|
||||
if paypal_response != 'VERIFIED':
|
||||
msg = ("Expecting 'VERIFIED' from PayPal, got '%s'. "
|
||||
"Failing." % paypal_response)
|
||||
_log_error_with_data(msg, request)
|
||||
return http.HttpResponseForbidden('Invalid confirmation')
|
||||
|
||||
if request.POST.get('txn_type', '').startswith('subscr_'):
|
||||
SubscriptionEvent.objects.create(post_data=php.serialize(request.POST))
|
||||
if post.get('txn_type', '').startswith('subscr_'):
|
||||
SubscriptionEvent.objects.create(post_data=php.serialize(post))
|
||||
return http.HttpResponse('Success!')
|
||||
|
||||
# We only care about completed transactions.
|
||||
if request.POST.get('payment_status') != 'Completed':
|
||||
if post.get('payment_status') != 'Completed':
|
||||
return http.HttpResponse('Payment not completed')
|
||||
|
||||
# Make sure transaction has not yet been processed.
|
||||
if (Contribution.objects
|
||||
.filter(transaction_id=request.POST['txn_id']).count()) > 0:
|
||||
.filter(transaction_id=post['txn_id']).count()) > 0:
|
||||
return http.HttpResponse('Transaction already processed')
|
||||
|
||||
# Fetch and update the contribution - item_number is the uuid we created.
|
||||
try:
|
||||
c = Contribution.objects.get(uuid=request.POST['item_number'])
|
||||
c = Contribution.objects.get(uuid=post['item_number'])
|
||||
except Contribution.DoesNotExist:
|
||||
key = "%s%s:%s" % (settings.CACHE_PREFIX, 'contrib',
|
||||
request.POST['item_number'])
|
||||
post['item_number'])
|
||||
count = cache.get(key, 0) + 1
|
||||
|
||||
paypal_log.warning('Contribution (uuid=%s) not found for IPN request '
|
||||
'#%s.' % (request.POST['item_number'], count))
|
||||
'#%s.' % (post['item_number'], count))
|
||||
if count > 10:
|
||||
msg = ("Paypal sent a transaction that we don't know "
|
||||
"about and we're giving up on it.")
|
||||
|
@ -251,10 +261,10 @@ def _paypal(request):
|
|||
cache.set(key, count, 1209600) # This is 2 weeks.
|
||||
return http.HttpResponseServerError('Contribution not found')
|
||||
|
||||
c.transaction_id = request.POST['txn_id']
|
||||
c.amount = request.POST['mc_gross']
|
||||
c.transaction_id = post['txn_id']
|
||||
c.amount = post['mc_gross']
|
||||
c.uuid = None
|
||||
c.post_data = php.serialize(request.POST)
|
||||
c.post_data = php.serialize(post)
|
||||
c.save()
|
||||
|
||||
# Send thankyou email.
|
||||
|
|
|
@ -13,6 +13,8 @@ log = commonware.log.getLogger('z.cake')
|
|||
|
||||
|
||||
class SessionBackend:
|
||||
supports_anonymous_user = False
|
||||
supports_object_permissions = False
|
||||
|
||||
def authenticate(self, session):
|
||||
"""
|
||||
|
|
|
@ -122,7 +122,10 @@ class File(amo.models.ModelBase):
|
|||
def cleanup_file(sender, instance, **kw):
|
||||
""" On delete of the file object from the database, unlink the file from
|
||||
the file system """
|
||||
filename = instance.file_path
|
||||
try:
|
||||
filename = instance.file_path
|
||||
except models.ObjectDoesNotExist:
|
||||
return
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
|
||||
|
|
|
@ -532,7 +532,7 @@ class StatsDictField(models.TextField):
|
|||
description = 'A dictionary of counts stored as serialized php.'
|
||||
__metaclass__ = models.SubfieldBase
|
||||
|
||||
def db_type(self):
|
||||
def db_type(self, connection):
|
||||
return 'text'
|
||||
|
||||
def to_python(self, value):
|
||||
|
@ -561,7 +561,7 @@ class StatsDictField(models.TextField):
|
|||
return StatsDict(d)
|
||||
return None
|
||||
|
||||
def get_db_prep_value(self, value):
|
||||
def get_db_prep_value(self, value, connection, prepared=False):
|
||||
if value is None or value == '':
|
||||
return value
|
||||
try:
|
||||
|
|
|
@ -4,6 +4,8 @@ from .models import UserProfile
|
|||
|
||||
|
||||
class AmoUserBackend(object):
|
||||
supports_anonymous_user = False
|
||||
supports_object_permissions = False
|
||||
|
||||
def authenticate(self, username=None, password=None):
|
||||
try:
|
||||
|
|
|
@ -109,6 +109,11 @@ class UserRegisterForm(happyforms.ModelForm):
|
|||
if not settings.RECAPTCHA_PRIVATE_KEY:
|
||||
del self.fields['recaptcha']
|
||||
|
||||
errors = {'invalid': _('This URL has an invalid format. '
|
||||
'Valid URLs look like '
|
||||
'http://example.com/my_page.')}
|
||||
self.fields['homepage'].error_messages = errors
|
||||
|
||||
def clean_email(self):
|
||||
d = self.cleaned_data['email'].split('@')[-1]
|
||||
if BlacklistedEmailDomain.blocked(d):
|
||||
|
|
|
@ -97,10 +97,7 @@ class UserProfile(amo.models.ModelBase):
|
|||
display_collections_fav = models.BooleanField(default=False)
|
||||
emailhidden = models.BooleanField(default=False)
|
||||
homepage = models.URLField(max_length=255, blank=True, default='',
|
||||
verify_exists=False, error_messages={
|
||||
'invalid': _('This URL has an invalid format. '
|
||||
'Valid URLs look like '
|
||||
'http://example.com/my_page.')})
|
||||
verify_exists=False)
|
||||
location = models.CharField(max_length=255, blank=True, default='')
|
||||
notes = models.TextField(blank=True, null=True)
|
||||
notifycompat = models.BooleanField(default=True)
|
||||
|
|
|
@ -28,9 +28,10 @@ def flagged(request):
|
|||
|
||||
if request.method == 'POST':
|
||||
ids = map(int, request.POST.getlist('addon_id'))
|
||||
addons = list(addons)
|
||||
Addon.objects.filter(id__in=ids).update(admin_review=False)
|
||||
# The sql update doesn't invalidate anything, do it manually.
|
||||
invalid = [addon for addon in addons if addon.id in ids]
|
||||
invalid = [addon for addon in addons if addon.pk in ids]
|
||||
Addon.objects.invalidate(*invalid)
|
||||
return redirect('zadmin.flagged')
|
||||
|
||||
|
|
|
@ -65,5 +65,4 @@ for logger in cfg['loggers'].values() + [cfg['root']]:
|
|||
if logger is not cfg['root'] and 'propagate' not in logger:
|
||||
logger['propagate'] = False
|
||||
|
||||
|
||||
dictconfig.dictConfig(cfg)
|
||||
|
|
17
settings.py
17
settings.py
|
@ -155,12 +155,12 @@ SECRET_KEY = 'r#%9w^o_80)7f%!_ir5zx$tu3mupw9u%&s!)-_q%gy7i+fhx#)'
|
|||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.load_template_source',
|
||||
'django.template.loaders.app_directories.load_template_source',
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
)
|
||||
|
||||
TEMPLATE_CONTEXT_PROCESSORS = (
|
||||
'django.core.context_processors.auth',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.core.context_processors.debug',
|
||||
'django.core.context_processors.media',
|
||||
'django.core.context_processors.request',
|
||||
|
@ -580,11 +580,12 @@ HERA = [{'USERNAME': '',
|
|||
LOG_LEVEL = logging.DEBUG
|
||||
HAS_SYSLOG = True # syslog is used if HAS_SYSLOG and NOT DEBUG.
|
||||
SYSLOG_TAG = "http_app_addons"
|
||||
# See PEP 391 and log_settings.py for formatting help. Each section of LOGGING
|
||||
# will get merged into the corresponding section of log_settings.py.
|
||||
# Handlers and log levels are set up automatically based on LOG_LEVEL and DEBUG
|
||||
# unless you set them here. Messages will not propagate through a logger
|
||||
# unless propagate: True is set.
|
||||
# See PEP 391 and log_settings.py for formatting help. Each section of
|
||||
# LOGGING will get merged into the corresponding section of
|
||||
# log_settings.py. Handlers and log levels are set up automatically based
|
||||
# on LOG_LEVEL and DEBUG unless you set them here. Messages will not
|
||||
# propagate through a logger unless propagate: True is set.
|
||||
LOGGING_CONFIG = None
|
||||
LOGGING = {
|
||||
'loggers': {
|
||||
'amqplib': {'handlers': ['null']},
|
||||
|
|
Загрузка…
Ссылка в новой задаче