Django

Code

Changeset 998

Show
Ignore:
Timestamp:
10/23/05 10:45:02 (3 years ago)
Author:
rjwittams
Message:

Synced to trunk. Fixed views/decorators/auth.py. Added extra customisation points to admin change_forms.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/new-admin/django/contrib/admin/templates/admin/change_form.html

    r982 r998  
    2020  </ul> 
    2121{% endif %}{% endif %} 
    22 <form {{ form_enc_attrib }} action='{{ form_url }}' method="post"> 
    23  
     22<form {{ form_enc_attrib }} action='{{ form_url }}' method="post">{% block form_top %}{%endblock%} 
    2423{% if is_popup %}<input type="hidden" name="_popup" value="1">{% endif %} 
    2524{% if save_on_top %}{% submit_row %}{% endif %} 
     
    3635   </fieldset> 
    3736{% endfor %} 
     37{% block after_field_sets %}{% endblock %} 
    3838{% if change %} 
    3939   {% if ordered_objects %} 
     
    4545   {% endif %} 
    4646{% endif %} 
     47 
    4748{% for related_object in inline_related_objects %}{% edit_inline related_object %}{% endfor %} 
     49{% block after_related_objects%}{%endblock%} 
    4850{% submit_row %} 
    4951{% if add %} 
  • django/branches/new-admin/django/contrib/admin/views/main.py

    r982 r998  
    608608         
    609609         
    610 def fill_extra_context(opts, app_label, context, add=False, change=False, show_delete=False, form_url=''): 
     610def render_change_form(opts, app_label, context, add=False, change=False, show_delete=False, form_url=''): 
    611611    ordered_objects = opts.get_ordered_objects()[:] 
    612612    auto_populated_fields = [f for f in opts.fields if f.prepopulate_from] 
     
    651651    } 
    652652     
    653     context.update(extra_context)    
     653    context.update(extra_context) 
     654     
     655    return render_to_response(["admin/%s/%s/change_form" % (app_label, opts.object_name.lower() ),  
     656                               "admin/%s/change_form" % app_label ,  
     657                               "admin/change_form"],  
     658                              context_instance=context) 
    654659    
    655     
     660def log_add_message(user, opts,manipulator,new_object): 
     661    pk_value = getattr(new_object, opts.pk.column) 
     662    log.log_action(user.id, opts.get_content_type_id(), pk_value, repr(new_object), log.ADDITION) 
     663 
    656664def add_stage(request, app_label, module_name, show_delete=False, form_url='', post_url='../', post_url_continue='../%s/', object_id_override=None): 
    657665    mod, opts = _get_mod_opts(app_label, module_name) 
     
    667675         
    668676        if not errors and not request.POST.has_key("_preview"): 
    669             for f in opts.many_to_many: 
    670                 if f.rel.raw_id_admin: 
    671                     new_data.setlist(f.name, new_data[f.name].split(",")) 
    672677            new_object = manipulator.save(new_data) 
    673             pk_value = getattr(new_object, opts.pk.column) 
    674             log.log_action(request.user.id, opts.get_content_type_id(), pk_value, repr(new_object), log.ADDITION) 
     678            log_add_message(request.user, opts,manipulator,new_object) 
    675679            msg = 'The %s "%s" was added successfully.' % (opts.verbose_name, new_object) 
     680             
    676681            # Here, we distinguish between different save types by checking for 
    677682            # the presence of keys in request.POST. 
     
    690695                request.user.add_message(msg) 
    691696                return HttpResponseRedirect(post_url) 
    692        # if request.POST.has_key("_preview"):   # Always happens anyway.  
    693        #     manipulator.do_html2python(new_data) 
    694697    else: 
    695698        # Add default data. 
     
    711714        c['object_id'] = object_id_override 
    712715     
     716    return render_change_form(opts, app_label, c, add=True) 
     717add_stage = staff_member_required(add_stage) 
     718 
     719def log_change_message(user, opts,manipulator,new_object): 
     720    pk_value = getattr(new_object, opts.pk.column) 
     721    # Construct the change message. 
     722    change_message = [] 
     723    if manipulator.fields_added: 
     724        change_message.append('Added %s.' % get_text_list(manipulator.fields_added, 'and')) 
     725    if manipulator.fields_changed: 
     726        change_message.append('Changed %s.' % get_text_list(manipulator.fields_changed, 'and')) 
     727    if manipulator.fields_deleted: 
     728        change_message.append('Deleted %s.' % get_text_list(manipulator.fields_deleted, 'and')) 
     729    change_message = ' '.join(change_message) 
     730    if not change_message: 
     731        change_message = 'No fields changed.' 
     732    log.log_action(user.id, opts.get_content_type_id(), pk_value, repr(new_object), log.CHANGE, change_message) 
    713733     
    714     fill_extra_context(opts, app_label, c, add=True) 
    715     
    716     return render_to_response("admin/change_form", context_instance=c)  
    717 add_stage = staff_member_required(add_stage) 
    718  
    719  
    720734def change_stage(request, app_label, module_name, object_id): 
    721735    mod, opts = _get_mod_opts(app_label, module_name) 
     
    738752        manipulator.do_html2python(new_data) 
    739753        if not errors and not request.POST.has_key("_preview"): 
    740         # Now done in commaseparatedint 
    741         #    for f in opts.many_to_many:  
    742         #        if f.rel.raw_id_admin: 
    743         #            new_data.setlist(f.name, new_data[f.name].split(",")) 
    744754            new_object = manipulator.save(new_data) 
    745             pk_value = getattr(new_object, opts.pk.column) 
    746  
    747             # Construct the change message. 
    748             change_message = [] 
    749             if manipulator.fields_added: 
    750                 change_message.append('Added %s.' % get_text_list(manipulator.fields_added, 'and')) 
    751             if manipulator.fields_changed: 
    752                 change_message.append('Changed %s.' % get_text_list(manipulator.fields_changed, 'and')) 
    753             if manipulator.fields_deleted: 
    754                 change_message.append('Deleted %s.' % get_text_list(manipulator.fields_deleted, 'and')) 
    755             change_message = ' '.join(change_message) 
    756             if not change_message: 
    757                 change_message = 'No fields changed.' 
    758  
    759             log.log_action(request.user.id, opts.get_content_type_id(), pk_value, repr(new_object), log.CHANGE, change_message) 
     755            log_change_message(request.user,opts,manipulator,new_object) 
    760756            msg = 'The %s "%s" was changed successfully.' % (opts.verbose_name, new_object) 
    761757            if request.POST.has_key("_continue"): 
     
    774770                request.user.add_message(msg) 
    775771                return HttpResponseRedirect("../") 
    776        # if request.POST.has_key("_preview"):  # always happens 
    777        #     manipulator.do_html2python(new_data) 
    778772    else: 
    779773        # Populate new_data with a "flattened" version of the current data. 
    780774        new_data = manipulator.flatten_data() 
    781775        
    782   
     776        # TODO: do this in flatten_data...  
    783777        # If the object has ordered objects on its admin page, get the existing 
    784778        # order and flatten it into a comma-separated list of IDs. 
     779         
    785780        id_order_list = [] 
    786781        for rel_obj in opts.get_ordered_objects(): 
     
    795790    form.order_objects = [] 
    796791     
     792    #TODO Should be done in flatten_data  / FormWrapper construction 
    797793    for related in opts.get_followed_related_objects(): 
    798794        wrt = related.opts.order_with_respect_to 
     
    811807    }) 
    812808 
    813     fill_extra_context(opts, app_label, c, change=True) 
     809    return render_change_form(opts, app_label, c, change=True) 
    814810     
    815     return render_to_response('admin/change_form', context_instance=c) 
    816 change_stage = staff_member_required(change_stage) 
     811     
    817812 
    818813def _nest_help(obj, depth, val): 
  • django/branches/new-admin/django/core/meta/__init__.py

    r986 r998  
    14991499    id_list = args and args[0] or kwargs['id_list'] 
    15001500    assert id_list != [], "get_in_bulk() cannot be passed an empty list." 
    1501     kwargs['where'] = ["%s.id IN (%s)" % (opts.db_table, ",".join(map(str, id_list)))] 
     1501    kwargs['where'] = ["%s.%s IN (%s)" % (opts.db_table, opts.pk.column, ",".join(['%s'] * len(id_list)))] 
     1502    kwargs['params'] = id_list 
    15021503    obj_list = function_get_list(opts, klass, **kwargs) 
    1503     return dict([(o.id, o) for o in obj_list]) 
     1504    return dict([(getattr(o, opts.pk.column), o) for o in obj_list]) 
    15041505 
    15051506def function_get_latest(opts, klass, does_not_exist_exception, **kwargs): 
  • django/branches/new-admin/django/utils/dateformat.py

    r980 r998  
    1313 
    1414from django.utils.dates import MONTHS, MONTHS_AP, WEEKDAYS 
     15from django.utils.tzinfo import LocalTimezone 
    1516from calendar import isleap 
    16 import re 
     17import re, time 
    1718 
    1819re_formatchars = re.compile(r'(?<!\\)([aABdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ])') 
     
    4142    def A(self): 
    4243        "'AM' or 'PM'" 
    43         return self.a().upper() 
     44        if self.data.hour > 11: 
     45            return 'PM' 
     46        return 'AM' 
    4447 
    4548    def B(self): 
     
    101104    year_days = [None, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334] 
    102105 
    103     def __init__(self, d): 
    104         self.data = d 
     106    def __init__(self, dt): 
     107        # Accepts either a datetime or date object. 
     108        self.data = dt 
     109        self.timezone = getattr(dt, 'tzinfo', None) 
     110        if hasattr(self.data, 'hour') and not self.timezone: 
     111            self.timezone = LocalTimezone(dt) 
    105112 
    106113    def d(self): 
     
    120127        raise NotImplementedError 
    121128 
     129    def I(self): 
     130        "'1' if Daylight Savings Time, '0' otherwise." 
     131        if self.timezone.dst(self.data): 
     132            return '1' 
     133        else: 
     134            return '0' 
     135 
    122136    def j(self): 
    123137        "Day of the month without leading zeros; i.e. '1' to '31'" 
     
    150164    def O(self): 
    151165        "Difference to Greenwich time in hours; e.g. '+0200'" 
    152         raise NotImplementedError 
     166        tz = self.timezone.utcoffset(self.data) 
     167        return "%+03d%02d" % (tz.seconds // 3600, (tz.seconds // 60) % 60) 
    153168 
    154169    def r(self): 
    155170        "RFC 822 formatted date; e.g. 'Thu, 21 Dec 2000 16:01:07 +0200'" 
    156         raise NotImplementedError 
     171        return self.format('D, j M Y H:i:s O') 
    157172 
    158173    def S(self): 
     
    175190    def T(self): 
    176191        "Time zone of this machine; e.g. 'EST' or 'MDT'" 
    177         raise NotImplementedError 
     192        name = self.timezone.tzname(self.data) 
     193        if name is None: 
     194            name = self.format('O') 
     195        return name 
    178196 
    179197    def U(self): 
    180198        "Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)" 
    181         raise NotImplementedError 
     199        off = self.timezone.utcoffset(self.data) 
     200        return int(time.mktime(self.data.timetuple())) + off.seconds * 60 
    182201 
    183202    def w(self): 
     
    230249        for timezones west of UTC is always negative, and for those east of UTC 
    231250        is always positive.""" 
    232         raise NotImplementedError 
     251        return self.timezone.utcoffset(self.data).seconds 
    233252 
    234253def format(value, format_string): 
  • django/branches/new-admin/django/utils/timesince.py

    r3 r998  
    1 import time, math, datetime 
     1import datetime, math, time 
     2from django.utils.tzinfo import LocalTimezone 
    23 
    34def timesince(d, now=None): 
     
    78    Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since 
    89    """ 
    9     original = time.mktime(d.timetuple()) 
    1010    chunks = ( 
    1111      (60 * 60 * 24 * 365, 'year'), 
     
    1515      (60, 'minute') 
    1616    ) 
    17     if not now: 
    18         now = time.time() 
    19     since = now - original 
     17    if now: 
     18        t = time.mktime(now) 
     19    else: 
     20        t = time.localtime() 
     21    if d.tzinfo: 
     22        tz = LocalTimezone() 
     23    else: 
     24        tz = None 
     25    now = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz) 
     26    delta = now - d 
     27    since = delta.days * 24 * 60 * 60 + delta.seconds 
    2028    # Crazy iteration syntax because we need i to be current index 
    2129    for i, (seconds, name) in zip(range(len(chunks)), chunks): 
  • django/branches/new-admin/django/views/decorators/auth.py

    r3 r998  
    1 def login_required(view_func): 
     1def user_passes_test(test_func): 
     2    """ 
     3    Decorator for views that checks that the user passes the given test, 
     4    redirecting to the log-in page if necessary. The test should be a callable 
     5    that takes the user object and returns True if the user passes. 
     6    """ 
     7     
     8    def _dec(view_func): 
     9        def _checklogin(request, *args, **kwargs): 
     10            from django.views.auth.login import redirect_to_login 
     11            if test_func(request.user): 
     12                return view_func(request, *args, **kwargs) 
     13            return redirect_to_login(request.path) 
     14        return _checklogin 
     15    return _dec 
     16 
     17 
     18login_required = user_passes_test(lambda u: not u.is_anonymous()) 
     19login_required.__doc__ = (  
    220    """ 
    321    Decorator for views that checks that the user is logged in, redirecting 
    422    to the log-in page if necessary. 
    523    """ 
    6     from django.views.auth.login import redirect_to_login 
    7     def _checklogin(request, *args, **kwargs): 
    8         if request.user.is_anonymous(): 
    9             return redirect_to_login(request.path) 
    10         else: 
    11             return view_func(request, *args, **kwargs) 
    12     return _checklogin 
     24    ) 
     25     
  • django/branches/new-admin/docs/templates.txt

    r987 r998  
    518518    N                 Month abbreviation in Associated Press  ``'Jan.'``, ``'Feb.'``, ``'March'``, ``'May'`` 
    519519                      style. Proprietary extension. 
    520     O                 Not implemented. 
     520    O                 Difference to Greenwich time in hours.  ``'+0200'`` 
    521521    P                 Time, in 12-hour hours, minutes and     ``'1 a.m.'``, ``'1:30 p.m.'``, ``'midnight'``, ``'noon'``, ``'12:30 p.m.'`` 
    522522                      'a.m.'/'p.m.', with minutes left off 
     
    524524                      strings 'midnight' and 'noon' if 
    525525                      appropriate. Proprietary extension. 
    526     r                 Not implemented. 
     526    r                 RFC 822 formatted date.                 ``'Thu, 21 Dec 2000 16:01:07 +0200'`` 
    527527    s                 Seconds, 2 digits with leading zeros.   ``'00'`` to ``'59'`` 
    528528    S                 English ordinal suffix for day of the   ``'st'``, ``'nd'``, ``'rd'`` or ``'th'`` 
    529529                      month, 2 characters. 
    530530    t                 Not implemented. 
    531     T                 Not implemented. 
     531    T                 Time zone of this machine.              ``'EST'``, ``'MDT'`` 
    532532    U                 Not implemented. 
    533533    w                 Day of the week, digits without         ``'0'`` (Sunday) to ``'6'`` (Saturday) 
     
    538538    Y                 Year, 4 digits.                         ``'1999'`` 
    539539    z                 Day of the year.                        ``0`` to ``365`` 
    540     Z                 Not implemented. 
     540    Z                 Time zone offset in seconds. The        ``-43200`` to ``43200`` 
     541                      offset for timezones west of UTC is 
     542                      always negative, and for those east of 
     543                      UTC is always positive. 
    541544    ================  ======================================  ===================== 
    542545 
  • django/branches/new-admin/tests/testapp/models/custom_pk.py

    r682 r998  
    5454>>> employees.get_list(last_name__exact='Jones') 
    5555[Dan Jones, Fran Jones] 
     56>>> employees.get_in_bulk(['ABC123', 'XYZ456']) 
     57{'XYZ456': Fran Jones, 'ABC123': Dan Jones} 
    5658 
    5759>>> b = businesses.Business(name='Sears') 
     
    6365>>> fran.get_business_list() 
    6466[Sears] 
     67>>> businesses.get_in_bulk(['Sears']) 
     68{'Sears': Sears} 
    6569"""