Skip to content

Commit

Permalink
Remove all special handling for Django 1.3 since it's no longer suppo…
Browse files Browse the repository at this point in the history
…rted.
  • Loading branch information
stephenmcd committed Mar 23, 2013
1 parent 560ed81 commit ed33b13
Show file tree
Hide file tree
Showing 20 changed files with 56 additions and 143 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
language: python
env:
- DJANGO_VERSION=1.3.1
- DJANGO_VERSION=1.4
- DJANGO_VERSION=1.5
python:
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ Dependencies
Mezzanine makes use of as few libraries as possible (apart from a
standard Django environment), with the following dependencies:

* `Python`_ 2.5 ... 2.7
* `Django`_ 1.3 ... 1.4
* `Python`_ 2.6 / 2.7
* `Django`_ 1.4 / 1.5
* `Python Imaging Library`_ - for image resizing
* `grappelli-safe`_ - admin skin (`Grappelli`_ fork)
* `filebrowser-safe`_ - for managing file uploads (`FileBrowser`_ fork)
Expand Down
1 change: 0 additions & 1 deletion mezzanine/bin/mezzanine_project.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env python

from __future__ import with_statement
from distutils.dir_util import copy_tree
from optparse import OptionParser
import os
Expand Down
16 changes: 2 additions & 14 deletions mezzanine/blog/feeds.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
try:
# Django <= 1.3
from django.contrib.syndication.feeds import Feed
except ImportError:
# Django >= 1.4
from django.contrib.syndication.views import Feed

from django.contrib.syndication.views import Feed
from django.core.urlresolvers import reverse
from django.shortcuts import get_object_or_404
from django.utils.feedgenerator import Atom1Feed
from django.utils.html import strip_tags
from django import VERSION

from mezzanine.blog.models import BlogPost, BlogCategory
from mezzanine.generic.models import Keyword
Expand Down Expand Up @@ -51,13 +46,6 @@ def __init__(self, *args, **kwargs):
self.title = settings.SITE_TITLE
self.description = settings.SITE_TAGLINE

def get_feed(self, *args, **kwargs):
# Django 1.3 author/category/tag filtering.
if VERSION < (1, 4) and args[0]:
attr, value = args[0].split("/", 1)
setattr(self, attr, value)
return super(PostsRSS, self).get_feed(*args, **kwargs)

def link(self):
return reverse("blog_post_feed", kwargs={"format": "rss"})

Expand Down
16 changes: 11 additions & 5 deletions mezzanine/blog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,22 @@ def get_absolute_url(self):
})
return (url_name, (), kwargs)

# These methods are wrappers for keyword and category access.
# For Django 1.3, we manually assign keywords and categories
# in the blog_post_list view, since we can't use Django 1.4's
# prefetch_related method. Once we drop support for Django 1.3,
# these can probably be removed.
# These methods are deprectaed wrappers for keyword and category
# access. They existed to support Django 1.3 with prefetch_related
# not existing, which was therefore manually implemented in the
# blog list views. All this is gone now, but the access methods
# still exist for older templates.

def category_list(self):
from warnings import warn
warn("blog_post.category_list in templates is deprecated"
"use blog_post.categories.all which are prefetched")
return getattr(self, "_categories", self.categories.all())

def keyword_list(self):
from warnings import warn
warn("blog_post.keyword_list in templates is deprecated"
"use the keywords_for template tag, as keywords are prefetched")
try:
return self._keywords
except AttributeError:
Expand Down
11 changes: 7 additions & 4 deletions mezzanine/blog/templates/blog/blog_post_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,14 @@ <h6>
{% with blog_post.user as author %}
<a href="{% url "blog_post_list_author" author %}">{{ author.get_full_name|default:author.username }}</a>
{% endwith %}
{% if blog_post.category_list %}
{% with blog_post.category.all as categories %}
{% if categories %}
{% trans "in" %}
{% for category in blog_post.category_list %}
{% for category in categories %}
<a href="{% url "blog_post_list_category" category.slug %}">{{ category }}</a>
{% endfor %}
{% endif %}
{% endwith %}
{% blocktrans with sometime=blog_post.publish_date|timesince %}{{ sometime }} ago{% endblocktrans %}
</h6>
{% endeditable %}
Expand All @@ -109,10 +111,11 @@ <h6>

{% block blog_post_list_post_links %}
<p class="blog-list-detail">
{% if blog_post.keyword_list %}
{% keywords_for blog_post as tags %}
{% if tags %}
{% trans "Tags" %}:
{% spaceless %}
{% for tag in blog_post.keyword_list %}
{% for tag in tags %}
<a href="{% url "blog_post_list_tag" tag.slug %}" class="tag">{{ tag }}</a>
{% endfor %}
{% endspaceless %}
Expand Down
59 changes: 5 additions & 54 deletions mezzanine/blog/views.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
from calendar import month_name
from collections import defaultdict

from django.http import Http404
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404
from django import VERSION

from mezzanine.blog.models import BlogPost, BlogCategory
from mezzanine.blog.feeds import PostsRSS, PostsAtom
from mezzanine.conf import settings
from mezzanine.generic.models import AssignedKeyword, Keyword
from mezzanine.generic.models import Keyword
from mezzanine.utils.views import render, paginate
from mezzanine.utils.models import get_user_model

Expand Down Expand Up @@ -46,41 +43,8 @@ def blog_post_list(request, tag=None, year=None, month=None, username=None,
blog_posts = blog_posts.filter(user=author)
templates.append(u"blog/blog_post_list_%s.html" % username)

# We want to iterate keywords and categories for each blog post
# without triggering "num posts x 2" queries.
#
# For Django 1.3 we create dicts mapping blog post IDs to lists of
# categories and keywords, and assign these to attributes on each
# blog post. The Blog model then uses accessor methods to retrieve
# these attributes when assigned, which will fall back to the real
# related managers for Django 1.4 and higher, which will already
# have their data retrieved via prefetch_related.

blog_posts = blog_posts.select_related("user")
if VERSION >= (1, 4):
blog_posts = blog_posts.prefetch_related("categories",
"keywords__keyword")
else:
categories = defaultdict(list)
if blog_posts:
ids = ",".join([str(p.id) for p in blog_posts])
for cat in BlogCategory.objects.raw(
"SELECT * FROM blog_blogcategory "
"JOIN blog_blogpost_categories "
"ON blog_blogcategory.id = blogcategory_id "
"WHERE blogpost_id IN (%s)" % ids):
categories[cat.blogpost_id].append(cat)
keywords = defaultdict(list)
blogpost_type = ContentType.objects.get(app_label="blog",
model="blogpost")
assigned = AssignedKeyword.objects.filter(blogpost__in=blog_posts,
content_type=blogpost_type).select_related("keyword")
for a in assigned:
keywords[a.object_pk].append(a.keyword)
for i, post in enumerate(blog_posts):
setattr(blog_posts[i], "_categories", categories[post.id])
setattr(blog_posts[i], "_keywords", keywords[post.id])

prefetch = ("categories", "keywords__keyword")
blog_posts = blog_posts.select_related("user").prefetch_related(*prefetch)
blog_posts = paginate(blog_posts, request.GET.get("page", 1),
settings.BLOG_POST_PER_PAGE,
settings.MAX_PAGING_LINKS)
Expand All @@ -106,22 +70,9 @@ def blog_post_detail(request, slug, year=None, month=None, day=None,

def blog_post_feed(request, format, **kwargs):
"""
Blog posts feeds - handle difference between Django 1.3 and 1.4
Blog posts feeds - maps format to the correct feed view.
"""
blog_feed_dict = {"rss": PostsRSS, "atom": PostsAtom}
try:
blog_feed_dict[format]
return {"rss": PostsRSS, "atom": PostsAtom}[format](**kwargs)(request)
except KeyError:
raise Http404()
try:
# Django <= 1.3
from django.contrib.syndication.views import feed
except ImportError:
# Django >= 1.4
return blog_feed_dict[format](**kwargs)(request)
else:
if len(kwargs) == 1:
# /author/foo/ or /tag/bar/ or /category/baz/
# gets extracted in get_feed method of feed class.
format += "/%s/%s" % kwargs.items()[0]
return feed(request, format, feed_dict=blog_feed_dict)
2 changes: 1 addition & 1 deletion mezzanine/core/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from django.db.models.manager import ManagerDescriptor
from django.db.models.query import QuerySet
from django.contrib.sites.managers import CurrentSiteManager as DjangoCSM
from django.utils.timezone import now

from mezzanine.conf import settings
from mezzanine.utils.sites import current_site_id
from mezzanine.utils.timezone import now


class PublishedManager(Manager):
Expand Down
2 changes: 1 addition & 1 deletion mezzanine/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.template.defaultfilters import truncatewords_html
from django.utils.html import strip_tags
from django.utils.timesince import timesince
from django.utils.timezone import now
from django.utils.translation import ugettext, ugettext_lazy as _

from mezzanine.core.fields import RichTextField
Expand All @@ -14,7 +15,6 @@
from mezzanine.utils.html import TagCloser
from mezzanine.utils.models import base_concrete_model, get_user_model_name
from mezzanine.utils.sites import current_site_id
from mezzanine.utils.timezone import now
from mezzanine.utils.urls import admin_url, slugify


Expand Down
1 change: 0 additions & 1 deletion mezzanine/core/templatetags/mezzanine_tags.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

from __future__ import with_statement
from hashlib import md5
import os
from urllib import urlopen, urlencode, quote, unquote
Expand Down
2 changes: 1 addition & 1 deletion mezzanine/core/tests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from __future__ import with_statement

import os
from shutil import rmtree
from urlparse import urlparse
Expand Down
1 change: 0 additions & 1 deletion mezzanine/core/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

from __future__ import with_statement
import os
from urlparse import urljoin, urlparse

Expand Down
13 changes: 4 additions & 9 deletions mezzanine/forms/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
from os.path import join, split
from uuid import uuid4

import django
from django import forms
from django.forms.extras import SelectDateWidget
from django.core.files.storage import FileSystemStorage
from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.utils.timezone import now

from mezzanine.conf import settings
from mezzanine.forms import fields
from mezzanine.forms.models import FormEntry, FieldEntry
from mezzanine.utils.timezone import now


fs = FileSystemStorage(location=settings.FORMS_UPLOAD_ROOT)
Expand Down Expand Up @@ -131,8 +130,8 @@ def __init__(self, form, *args, **kwargs):
self.fields[field_key] = field_class(**field_args)

if field.field_type == fields.DOB:
now = datetime.now()
years = range(now.year, now.year - 120, -1)
_now = datetime.now()
years = range(_now.year, _now.year - 120, -1)
self.fields[field_key].widget.years = years

# Add identifying type attr to the field for styling.
Expand Down Expand Up @@ -171,11 +170,7 @@ def save(self, **kwargs):
new = {"entry": entry, "field_id": field.id, "value": value}
new_entry_fields.append(FieldEntry(**new))
if new_entry_fields:
if django.VERSION >= (1, 4, 0):
FieldEntry.objects.bulk_create(new_entry_fields)
else:
for field_entry in new_entry_fields:
field_entry.save()
FieldEntry.objects.bulk_create(new_entry_fields)
return entry

def email_to(self):
Expand Down
17 changes: 8 additions & 9 deletions mezzanine/generic/templatetags/keyword_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from mezzanine import template
from mezzanine.conf import settings
from mezzanine.generic.fields import KeywordsField
from mezzanine.generic.models import AssignedKeyword, Keyword


Expand All @@ -25,14 +24,14 @@ def keywords_for(*args):
obj = args[0]
if hasattr(obj, "get_content_model"):
obj = obj.get_content_model() or obj
# There can only be one ``KeywordsField``, find it.
for field in obj._meta.many_to_many:
if isinstance(field, KeywordsField):
break
else:
return []
keywords_manager = getattr(obj, field.name)
return [a.keyword for a in keywords_manager.select_related("keyword")]
keywords_name = obj.get_keywordsfield_name()
keywords_queryset = getattr(obj, keywords_name).all()
# Keywords may have been prefetched already. If not, we
# need select_related for the actual keywords.
prefetched = getattr(obj, "_prefetched_objects_cache", {})
if keywords_name not in prefetched:
keywords_queryset = keywords_queryset.select_related("keyword")
return [assigned.keyword for assigned in keywords_queryset]

# Handle a model class.
try:
Expand Down
4 changes: 2 additions & 2 deletions mezzanine/twitter/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
from django.utils.html import urlize
from django.utils.simplejson import loads
from django.utils.translation import ugettext_lazy as _
from django.utils.timezone import get_default_timezone, make_aware
from django.conf import settings

from mezzanine.twitter.managers import TweetManager
from mezzanine.utils.timezone import make_aware
from mezzanine.twitter import (QUERY_TYPE_CHOICES, QUERY_TYPE_USER,
QUERY_TYPE_LIST, QUERY_TYPE_SEARCH)

Expand Down Expand Up @@ -91,7 +91,7 @@ def run(self):
tweet.text = ''.join(chars)
d = datetime.strptime(tweet_json["created_at"], date_format)
d -= timedelta(seconds=timezone)
tweet.created_at = make_aware(d)
tweet.created_at = make_aware(d, get_default_timezone())
tweet.save()
self.interested = False
self.save()
Expand Down
7 changes: 0 additions & 7 deletions mezzanine/utils/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,3 @@ def mezzanine_settings():
elif shortname == "mysql":
# Required MySQL collation for tests.
s["DATABASES"][key]["TEST_COLLATION"] = "utf8_general_ci"

# Remaining is for Django < 1.4
from django import VERSION
if VERSION >= (1, 4):
return
s["TEMPLATE_CONTEXT_PROCESSORS"] = list(s["TEMPLATE_CONTEXT_PROCESSORS"])
remove("TEMPLATE_CONTEXT_PROCESSORS", "django.core.context_processors.tz")
1 change: 0 additions & 1 deletion mezzanine/utils/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
documentation is generated.
"""

from __future__ import with_statement
from datetime import datetime
import os.path
from shutil import copyfile, move
Expand Down
11 changes: 3 additions & 8 deletions mezzanine/utils/tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

from __future__ import with_statement
from _ast import PyCF_ONLY_AST
import os
from shutil import copyfile, copytree
Expand All @@ -17,13 +16,6 @@
# Used to version subpackages.
"'__version__' imported but unused",

# Backward compatibility for feeds changed in Django 1.4
"redefinition of unused 'Feed'",
"redefinition of unused 'feed'",

# Backward compatibility for timezone support
"redefinition of unused 'now'",

# No caching fallback
"redefinition of function 'nevercache'",

Expand All @@ -43,6 +35,9 @@
# Django 1.5 custom user compatibility
"redefinition of unused 'get_user_model",

# Deprecated compat timezones for Django 1.3
"mezzanine/utils/timezone",

)


Expand Down
Loading

0 comments on commit ed33b13

Please sign in to comment.