Fixed #163 -- Added 'pk' database API option, which is a shorthand for (primary_key)__exact
git-svn-id: http://code.djangoproject.com/svn/django/trunk@316 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
f14c98e44c
commit
786c750c40
|
@ -78,7 +78,7 @@ class Comment(meta.Model):
|
||||||
"""
|
"""
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
try:
|
try:
|
||||||
return self.get_content_type().get_object_for_this_type(id__exact=self.object_id)
|
return self.get_content_type().get_object_for_this_type(pk=self.object_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ class FreeComment(meta.Model):
|
||||||
"""
|
"""
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
try:
|
try:
|
||||||
return self.get_content_type().get_object_for_this_type(id__exact=self.object_id)
|
return self.get_content_type().get_object_for_this_type(pk=self.object_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ class CommentFormNode(template.Node):
|
||||||
# We only have to do this validation if obj_id_lookup_var is provided,
|
# We only have to do this validation if obj_id_lookup_var is provided,
|
||||||
# because do_comment_form() validates hard-coded object IDs.
|
# because do_comment_form() validates hard-coded object IDs.
|
||||||
try:
|
try:
|
||||||
self.content_type.get_object_for_this_type(id__exact=self.obj_id)
|
self.content_type.get_object_for_this_type(pk=self.obj_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
context['display_form'] = False
|
context['display_form'] = False
|
||||||
else:
|
else:
|
||||||
|
@ -203,7 +203,7 @@ class DoCommentForm:
|
||||||
if tokens[3].isdigit():
|
if tokens[3].isdigit():
|
||||||
obj_id = tokens[3]
|
obj_id = tokens[3]
|
||||||
try: # ensure the object ID is valid
|
try: # ensure the object ID is valid
|
||||||
content_type.get_object_for_this_type(id__exact=obj_id)
|
content_type.get_object_for_this_type(pk=obj_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
raise template.TemplateSyntaxError, "'%s' tag refers to %s object with ID %s, which doesn't exist" % (self.tag_name, content_type.name, obj_id)
|
raise template.TemplateSyntaxError, "'%s' tag refers to %s object with ID %s, which doesn't exist" % (self.tag_name, content_type.name, obj_id)
|
||||||
else:
|
else:
|
||||||
|
@ -283,7 +283,7 @@ class DoCommentCount:
|
||||||
if tokens[3].isdigit():
|
if tokens[3].isdigit():
|
||||||
obj_id = tokens[3]
|
obj_id = tokens[3]
|
||||||
try: # ensure the object ID is valid
|
try: # ensure the object ID is valid
|
||||||
content_type.get_object_for_this_type(id__exact=obj_id)
|
content_type.get_object_for_this_type(pk=obj_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
raise template.TemplateSyntaxError, "'%s' tag refers to %s object with ID %s, which doesn't exist" % (self.tag_name, content_type.name, obj_id)
|
raise template.TemplateSyntaxError, "'%s' tag refers to %s object with ID %s, which doesn't exist" % (self.tag_name, content_type.name, obj_id)
|
||||||
else:
|
else:
|
||||||
|
@ -338,7 +338,7 @@ class DoGetCommentList:
|
||||||
if tokens[3].isdigit():
|
if tokens[3].isdigit():
|
||||||
obj_id = tokens[3]
|
obj_id = tokens[3]
|
||||||
try: # ensure the object ID is valid
|
try: # ensure the object ID is valid
|
||||||
content_type.get_object_for_this_type(id__exact=obj_id)
|
content_type.get_object_for_this_type(pk=obj_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
raise template.TemplateSyntaxError, "'%s' tag refers to %s object with ID %s, which doesn't exist" % (self.tag_name, content_type.name, obj_id)
|
raise template.TemplateSyntaxError, "'%s' tag refers to %s object with ID %s, which doesn't exist" % (self.tag_name, content_type.name, obj_id)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -197,7 +197,7 @@ def post_comment(request):
|
||||||
rating_range, rating_choices = [], []
|
rating_range, rating_choices = [], []
|
||||||
content_type_id, object_id = target.split(':') # target is something like '52:5157'
|
content_type_id, object_id = target.split(':') # target is something like '52:5157'
|
||||||
try:
|
try:
|
||||||
obj = contenttypes.get_object(id__exact=content_type_id).get_object_for_this_type(id__exact=object_id)
|
obj = contenttypes.get_object(pk=content_type_id).get_object_for_this_type(pk=object_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
raise Http404, "The comment form had an invalid 'target' parameter -- the object ID was invalid"
|
raise Http404, "The comment form had an invalid 'target' parameter -- the object ID was invalid"
|
||||||
option_list = options.split(',') # options is something like 'pa,ra'
|
option_list = options.split(',') # options is something like 'pa,ra'
|
||||||
|
@ -284,9 +284,9 @@ def post_free_comment(request):
|
||||||
if comments.get_security_hash(options, '', '', target) != security_hash:
|
if comments.get_security_hash(options, '', '', target) != security_hash:
|
||||||
raise Http404, "Somebody tampered with the comment form (security violation)"
|
raise Http404, "Somebody tampered with the comment form (security violation)"
|
||||||
content_type_id, object_id = target.split(':') # target is something like '52:5157'
|
content_type_id, object_id = target.split(':') # target is something like '52:5157'
|
||||||
content_type = contenttypes.get_object(id__exact=content_type_id)
|
content_type = contenttypes.get_object(pk=content_type_id)
|
||||||
try:
|
try:
|
||||||
obj = content_type.get_object_for_this_type(id__exact=object_id)
|
obj = content_type.get_object_for_this_type(pk=object_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
raise Http404, "The comment form had an invalid 'target' parameter -- the object ID was invalid"
|
raise Http404, "The comment form had an invalid 'target' parameter -- the object ID was invalid"
|
||||||
option_list = options.split(',')
|
option_list = options.split(',')
|
||||||
|
@ -336,8 +336,8 @@ def comment_was_posted(request):
|
||||||
if request.GET.has_key('c'):
|
if request.GET.has_key('c'):
|
||||||
content_type_id, object_id = request.GET['c'].split(':')
|
content_type_id, object_id = request.GET['c'].split(':')
|
||||||
try:
|
try:
|
||||||
content_type = contenttypes.get_object(id__exact=content_type_id)
|
content_type = contenttypes.get_object(pk=content_type_id)
|
||||||
obj = content_type.get_object_for_this_type(id__exact=object_id)
|
obj = content_type.get_object_for_this_type(pk=object_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
pass
|
pass
|
||||||
t = template_loader.get_template('comments/posted')
|
t = template_loader.get_template('comments/posted')
|
||||||
|
|
|
@ -19,14 +19,14 @@ def vote(request, comment_id, vote):
|
||||||
if request.user.is_anonymous():
|
if request.user.is_anonymous():
|
||||||
raise Http404, "Anonymous users cannot vote"
|
raise Http404, "Anonymous users cannot vote"
|
||||||
try:
|
try:
|
||||||
comment = comments.get_object(id__exact=comment_id)
|
comment = comments.get_object(pk=comment_id)
|
||||||
except comments.CommentDoesNotExist:
|
except comments.CommentDoesNotExist:
|
||||||
raise Http404, "Invalid comment ID"
|
raise Http404, "Invalid comment ID"
|
||||||
if comment.user_id == request.user.id:
|
if comment.user_id == request.user.id:
|
||||||
raise Http404, "No voting for yourself"
|
raise Http404, "No voting for yourself"
|
||||||
karma.vote(request.user.id, comment_id, rating)
|
karma.vote(request.user.id, comment_id, rating)
|
||||||
# Reload comment to ensure we have up to date karma count
|
# Reload comment to ensure we have up to date karma count
|
||||||
comment = comments.get_object(id__exact=comment_id)
|
comment = comments.get_object(pk=comment_id)
|
||||||
t = template_loader.get_template('comments/karma_vote_accepted')
|
t = template_loader.get_template('comments/karma_vote_accepted')
|
||||||
c = Context(request, {
|
c = Context(request, {
|
||||||
'comment': comment
|
'comment': comment
|
||||||
|
|
|
@ -16,7 +16,7 @@ def flag(request, comment_id):
|
||||||
the flagged `comments.comments` object
|
the flagged `comments.comments` object
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
comment = comments.get_object(id__exact=comment_id, site_id__exact=SITE_ID)
|
comment = comments.get_object(pk=comment_id, site_id__exact=SITE_ID)
|
||||||
except comments.CommentDoesNotExist:
|
except comments.CommentDoesNotExist:
|
||||||
raise Http404
|
raise Http404
|
||||||
if request.POST:
|
if request.POST:
|
||||||
|
@ -31,7 +31,7 @@ flag = login_required(flag)
|
||||||
|
|
||||||
def flag_done(request, comment_id):
|
def flag_done(request, comment_id):
|
||||||
try:
|
try:
|
||||||
comment = comments.get_object(id__exact=comment_id, site_id__exact=SITE_ID)
|
comment = comments.get_object(pk=comment_id, site_id__exact=SITE_ID)
|
||||||
except comments.CommentDoesNotExist:
|
except comments.CommentDoesNotExist:
|
||||||
raise Http404
|
raise Http404
|
||||||
t = template_loader.get_template('comments/flag_done')
|
t = template_loader.get_template('comments/flag_done')
|
||||||
|
@ -50,7 +50,7 @@ def delete(request, comment_id):
|
||||||
the flagged `comments.comments` object
|
the flagged `comments.comments` object
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
comment = comments.get_object(id__exact=comment_id, site_id__exact=SITE_ID)
|
comment = comments.get_object(pk=comment_id, site_id__exact=SITE_ID)
|
||||||
except comments.CommentDoesNotExist:
|
except comments.CommentDoesNotExist:
|
||||||
raise Http404
|
raise Http404
|
||||||
if not comments.user_is_moderator(request.user):
|
if not comments.user_is_moderator(request.user):
|
||||||
|
@ -72,7 +72,7 @@ delete = login_required(delete)
|
||||||
|
|
||||||
def delete_done(request, comment_id):
|
def delete_done(request, comment_id):
|
||||||
try:
|
try:
|
||||||
comment = comments.get_object(id__exact=comment_id, site_id__exact=SITE_ID)
|
comment = comments.get_object(pk=comment_id, site_id__exact=SITE_ID)
|
||||||
except comments.CommentDoesNotExist:
|
except comments.CommentDoesNotExist:
|
||||||
raise Http404
|
raise Http404
|
||||||
t = template_loader.get_template('comments/delete_done')
|
t = template_loader.get_template('comments/delete_done')
|
||||||
|
|
|
@ -1146,6 +1146,9 @@ def _parse_lookup(kwarg_items, opts, table_count=0):
|
||||||
params.extend(params2)
|
params.extend(params2)
|
||||||
continue
|
continue
|
||||||
lookup_list = kwarg.split(LOOKUP_SEPARATOR)
|
lookup_list = kwarg.split(LOOKUP_SEPARATOR)
|
||||||
|
# pk="value" is shorthand for (primary key)__exact="value"
|
||||||
|
if lookup_list[-1] == 'pk':
|
||||||
|
lookup_list = lookup_list[:-1] + [opts.pk.name, 'exact']
|
||||||
if len(lookup_list) == 1:
|
if len(lookup_list) == 1:
|
||||||
_throw_bad_kwarg_error(kwarg)
|
_throw_bad_kwarg_error(kwarg)
|
||||||
lookup_type = lookup_list.pop()
|
lookup_type = lookup_list.pop()
|
||||||
|
|
|
@ -222,7 +222,7 @@ class Session(meta.Model):
|
||||||
"Sets the necessary cookie in the given HttpResponse object, also updates last login time for user."
|
"Sets the necessary cookie in the given HttpResponse object, also updates last login time for user."
|
||||||
from django.models.auth import users
|
from django.models.auth import users
|
||||||
from django.conf.settings import REGISTRATION_COOKIE_DOMAIN
|
from django.conf.settings import REGISTRATION_COOKIE_DOMAIN
|
||||||
user = users.get_object(id__exact=user_id)
|
user = users.get_object(pk=user_id)
|
||||||
user.last_login = datetime.datetime.now()
|
user.last_login = datetime.datetime.now()
|
||||||
user.save()
|
user.save()
|
||||||
session = create_session(user_id)
|
session = create_session(user_id)
|
||||||
|
@ -274,7 +274,7 @@ class LogEntry(meta.Model):
|
||||||
|
|
||||||
def get_edited_object(self):
|
def get_edited_object(self):
|
||||||
"Returns the edited object represented by this log entry"
|
"Returns the edited object represented by this log entry"
|
||||||
return self.get_content_type().get_object_for_this_type(id__exact=self.object_id)
|
return self.get_content_type().get_object_for_this_type(pk=self.object_id)
|
||||||
|
|
||||||
def get_admin_url(self):
|
def get_admin_url(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -14,7 +14,7 @@ class Site(meta.Model):
|
||||||
def _module_get_current():
|
def _module_get_current():
|
||||||
"Returns the current site, according to the SITE_ID constant."
|
"Returns the current site, according to the SITE_ID constant."
|
||||||
from django.conf.settings import SITE_ID
|
from django.conf.settings import SITE_ID
|
||||||
return get_object(id__exact=SITE_ID)
|
return get_object(pk=SITE_ID)
|
||||||
|
|
||||||
class Package(meta.Model):
|
class Package(meta.Model):
|
||||||
db_table = 'packages'
|
db_table = 'packages'
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import inspect
|
|
||||||
from django.core import meta
|
from django.core import meta
|
||||||
from django import templatetags
|
from django import templatetags
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -14,6 +11,7 @@ try:
|
||||||
from django.parts.admin import doc
|
from django.parts.admin import doc
|
||||||
except ImportError:
|
except ImportError:
|
||||||
doc = None
|
doc = None
|
||||||
|
import inspect, os, re
|
||||||
|
|
||||||
# Exclude methods starting with these strings from documentation
|
# Exclude methods starting with these strings from documentation
|
||||||
MODEL_METHODS_EXCLUDE = ('_', 'add_', 'delete', 'save', 'set_')
|
MODEL_METHODS_EXCLUDE = ('_', 'add_', 'delete', 'save', 'set_')
|
||||||
|
@ -128,7 +126,7 @@ def view_index(request):
|
||||||
'module' : func.__module__,
|
'module' : func.__module__,
|
||||||
'title' : title,
|
'title' : title,
|
||||||
'site_id': settings_mod.SITE_ID,
|
'site_id': settings_mod.SITE_ID,
|
||||||
'site' : sites.get_object(id__exact=settings_mod.SITE_ID),
|
'site' : sites.get_object(pk=settings_mod.SITE_ID),
|
||||||
'url' : simplify_regex(regex),
|
'url' : simplify_regex(regex),
|
||||||
})
|
})
|
||||||
t = template_loader.get_template('doc/view_index')
|
t = template_loader.get_template('doc/view_index')
|
||||||
|
|
|
@ -7,8 +7,8 @@ from django.utils import httpwrappers
|
||||||
def shortcut(request, content_type_id, object_id):
|
def shortcut(request, content_type_id, object_id):
|
||||||
from django.models.core import contenttypes
|
from django.models.core import contenttypes
|
||||||
try:
|
try:
|
||||||
content_type = contenttypes.get_object(id__exact=content_type_id)
|
content_type = contenttypes.get_object(pk=content_type_id)
|
||||||
obj = content_type.get_object_for_this_type(id__exact=object_id)
|
obj = content_type.get_object_for_this_type(pk=object_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
raise Http404, "Content type %s object %s doesn't exist" % (content_type_id, object_id)
|
raise Http404, "Content type %s object %s doesn't exist" % (content_type_id, object_id)
|
||||||
if not hasattr(obj, 'get_absolute_url'):
|
if not hasattr(obj, 'get_absolute_url'):
|
||||||
|
|
|
@ -97,6 +97,19 @@ Multiple lookups are allowed, of course, and are translated as "AND"s::
|
||||||
|
|
||||||
...retrieves all polls published in January 2005 that have a question starting with "Would."
|
...retrieves all polls published in January 2005 that have a question starting with "Would."
|
||||||
|
|
||||||
|
For convenience, there's a ``pk`` lookup type, which translates into
|
||||||
|
``(primary_key)__exact``. In the polls example, these two statements are
|
||||||
|
equivalent::
|
||||||
|
|
||||||
|
polls.get_object(id__exact=3)
|
||||||
|
polls.get_object(pk=3)
|
||||||
|
|
||||||
|
``pk`` lookups also work across joins. In the polls example, these two
|
||||||
|
statements are equivalent::
|
||||||
|
|
||||||
|
choices.get_list(poll__id__exact=3)
|
||||||
|
choices.get_list(poll__pk=3)
|
||||||
|
|
||||||
Ordering
|
Ordering
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,12 @@ is created on the fly: No code generation necessary::
|
||||||
...
|
...
|
||||||
django.models.news.ReporterDoesNotExist: Reporter does not exist for {'id__exact': 2}
|
django.models.news.ReporterDoesNotExist: Reporter does not exist for {'id__exact': 2}
|
||||||
|
|
||||||
|
# Lookup by a primary key is the most common case, so Django provides a
|
||||||
|
# shortcut for primary-key exact lookups.
|
||||||
|
# The following is identical to reporters.get_object(id__exact=1).
|
||||||
|
>>> reporters.get_object(pk=1)
|
||||||
|
John Smith
|
||||||
|
|
||||||
# Create an article.
|
# Create an article.
|
||||||
>>> from datetime import datetime
|
>>> from datetime import datetime
|
||||||
>>> a = articles.Article(id=None, pub_date=datetime.now(), headline='Django is cool', article='Yeah.', reporter_id=1)
|
>>> a = articles.Article(id=None, pub_date=datetime.now(), headline='Django is cool', article='Yeah.', reporter_id=1)
|
||||||
|
@ -200,7 +206,7 @@ article_detail from above::
|
||||||
def article_detail(request, year, month, article_id):
|
def article_detail(request, year, month, article_id):
|
||||||
# Use the Django API to find an object matching the URL criteria.
|
# Use the Django API to find an object matching the URL criteria.
|
||||||
try:
|
try:
|
||||||
a = articles.get_object(pub_date__year=year, pub_date__month=month, id__exact=article_id)
|
a = articles.get_object(pub_date__year=year, pub_date__month=month, pk=article_id)
|
||||||
except articles.ArticleDoesNotExist:
|
except articles.ArticleDoesNotExist:
|
||||||
raise Http404
|
raise Http404
|
||||||
t = template_loader.get_template('news/article_detail')
|
t = template_loader.get_template('news/article_detail')
|
||||||
|
|
|
@ -372,14 +372,20 @@ Let's jump back into the Python interactive shell::
|
||||||
>>> polls.get_list(question__startswith='What')
|
>>> polls.get_list(question__startswith='What')
|
||||||
[What's up]
|
[What's up]
|
||||||
|
|
||||||
|
# Lookup by a primary key is the most common case, so Django provides a
|
||||||
|
# shortcut for primary-key exact lookups.
|
||||||
|
# The following is identical to polls.get_object(id__exact=1).
|
||||||
|
>>> polls.get_object(pk=1)
|
||||||
|
What's up
|
||||||
|
|
||||||
# Make sure our custom method worked.
|
# Make sure our custom method worked.
|
||||||
>>> p = polls.get_object(id__exact=1)
|
>>> p = polls.get_object(pk=1)
|
||||||
>>> p.was_published_today()
|
>>> p.was_published_today()
|
||||||
False
|
False
|
||||||
|
|
||||||
# Give the Poll a couple of Choices. Each one of these method calls does an
|
# Give the Poll a couple of Choices. Each one of these method calls does an
|
||||||
# INSERT statement behind the scenes and returns the new Choice object.
|
# INSERT statement behind the scenes and returns the new Choice object.
|
||||||
>>> p = polls.get_object(id__exact=1)
|
>>> p = polls.get_object(pk=1)
|
||||||
>>> p.add_choice(choice='Not much', votes=0)
|
>>> p.add_choice(choice='Not much', votes=0)
|
||||||
Not much
|
Not much
|
||||||
>>> p.add_choice(choice='The sky', votes=0)
|
>>> p.add_choice(choice='The sky', votes=0)
|
||||||
|
|
|
@ -242,7 +242,7 @@ for a given poll. Here's the view::
|
||||||
from django.core.exceptions import Http404
|
from django.core.exceptions import Http404
|
||||||
def detail(request, poll_id):
|
def detail(request, poll_id):
|
||||||
try:
|
try:
|
||||||
p = polls.get_object(id__exact=poll_id)
|
p = polls.get_object(pk=poll_id)
|
||||||
except polls.PollDoesNotExist:
|
except polls.PollDoesNotExist:
|
||||||
raise Http404
|
raise Http404
|
||||||
t = template_loader.get_template('polls/detail')
|
t = template_loader.get_template('polls/detail')
|
||||||
|
|
Loading…
Reference in New Issue