Example #1
0
    def test_iter_content(self):
        r = HttpResponse(['abc', 'def', 'ghi'])
        self.assertEqual(r.content, 'abcdefghi')

        #test iter content via property
        r = HttpResponse()
        r.content = ['idan', 'alex', 'jacob']
        self.assertEqual(r.content, 'idanalexjacob')

        r = HttpResponse()
        r.content = [1, 2, 3]
        self.assertEqual(r.content, '123')

        #test retrieval explicitly using iter and odd inputs
        r = HttpResponse()
        r.content = ['1', u'2', 3, unichr(1950)]
        result = []
        my_iter = r.__iter__()
        while True:
            try:
                result.append(my_iter.next())
            except StopIteration:
                break
        #'\xde\x9e' == unichr(1950).encode('utf-8')
        self.assertEqual(result, ['1', '2', '3', '\xde\x9e'])
        self.assertEqual(r.content, '123\xde\x9e')

        #with Content-Encoding header
        r = HttpResponse([1,1,2,4,8])
        r['Content-Encoding'] = 'winning'
        self.assertEqual(r.content, '11248')
        r.content = [unichr(1950),]
        self.assertRaises(UnicodeEncodeError,
                          getattr, r, 'content')
Example #2
0
    def test_iter_content(self):
        r = HttpResponse(['abc', 'def', 'ghi'])
        self.assertEqual(r.content, b'abcdefghi')

        #test iter content via property
        r = HttpResponse()
        r.content = ['idan', 'alex', 'jacob']
        self.assertEqual(r.content, b'idanalexjacob')

        r = HttpResponse()
        r.content = [1, 2, 3]
        self.assertEqual(r.content, b'123')

        #test retrieval explicitly using iter and odd inputs
        r = HttpResponse()
        r.content = ['1', '2', 3, '\u079e']
        my_iter = r.__iter__()
        result = list(my_iter)
        #'\xde\x9e' == unichr(1950).encode('utf-8')
        self.assertEqual(result, [b'1', b'2', b'3', b'\xde\x9e'])
        self.assertEqual(r.content, b'123\xde\x9e')

        #with Content-Encoding header
        r = HttpResponse([1,1,2,4,8])
        r['Content-Encoding'] = 'winning'
        self.assertEqual(r.content, b'11248')
        r.content = ['\u079e',]
        self.assertRaises(UnicodeEncodeError,
                          getattr, r, 'content')
Example #3
0
class ListBase(object):
    
    list_template = "raw_list.html"
    item_template = "raw_item.html"
    header_template = "raw_list_header.html"

    default_order = None
    
    columns = ['id']
    
    extra_context = {}
    
    args = None
    kwargs = None
    def __init__(self,*args,**kwargs):
        self.response_string = self.render(*args,**kwargs)
        self.response_object = HttpResponse(self.response_string)
        self.status_code = 200
    
    def populate_context(self,request,*args,**kwargs):
        return {}
        
    def header_default(self,request,field):
        return string.capwords(field.replace("_"," "))
    
    def default_formatter(self,request,object,field,args):
        if hasattr(object,"get_%s_display" % field):
            return getattr(object,"get_%s_display" % field)()
        
        return self.get_value(request,object,field)
    
    def view_link(self,object):
        return self.base_url + str(object.pk) + "/"
        
    def action_link(self,object,action='edit'):
        return self.view_link(object) + "%s/" % action.replace(" ","_")

    def show_buttons(self,request,object,field,args):
        output = []
        for field in args:
            if field == 'view':
                output.append("""<a href="%s">View</a>""" % self.view_link(object))
            else:
                output.append("""<a href="%s">%s</a>""" % (self.action_link(object,field),string.capwords(field)))
        
        return " ".join(output)
                
                
    default_column_spec = {'sortable':True,'sort_function':None,
                           'header':header_default,
                           'formatter':default_formatter,
                           'formatter_args':[]}
    
    column_spec = {'action':{'formatter':show_buttons,
                             'formatter_args':['edit','delete'],
                             'sortable':False},
                    'id':{'header':'ID'}}
    

    model = Book
    
    paginate_by = 10
    
    queryset = None
    
    def get_queryset(self,request,*args,**kwargs):
        return self.model.objects.all()
        
    def get_value(self,request,object,field):
        try:
            if callable(getattr(object,field)):
                v = getattr(object,field)()
            else:
                v = getattr(object,field)
            if v == None:
                v = ""
        except:
            v = ""
        return v
    
    def get_display_value(self,request,object,field):
        spec = self.get_column_spec(field)
        return spec['formatter'](self,request,object,field,spec['formatter_args'])
        
    def get_column_spec(self,field):
        spec = self.default_column_spec.copy()
        if self.column_spec.has_key(field):
            spec.update(self.column_spec[field].copy())
        
        return spec
    
    def __getattr__(self,name):
        if hasattr(self,"response_object") and hasattr(self.response_object,name):
            return getattr(self.response_object,name)
        raise AttributeError
    
    def __setattr__(self,name,value):
        if name == "content":
            self.response_object.content = value
        else:
            self.__dict__[name] = value
    
    def __iter__(self):
        if hasattr(self,"response_object"):
            return self.response_object.__iter__()
        return []
    
    def __getitem__(self,name):
        if hasattr(self,"response_object"):
            return self.response_object[name]
        raise AttributeError

    def __setitem__(self,name,value):
        if hasattr(self,"response_object"):
            self.response_object[name] = value
    
    def __str__(self):
        return str(self.response_string)
    
    def __unicode__(self):
        return self.response_string
    

    def __call__(self,request,*args,**kwargs):
        return HttpResponse(self.render(request,*args,**kwargs))

    def render(self,request,*args,**kwargs):
        if self.queryset == None:
            self.queryset = self.get_queryset(request,*args,**kwargs)

        self.base_url = request.path_info[:]

        sort_by = request.GET.get('sort',self.default_order)

        try:
            page = int(request.GET.get('page',1))
        except ValueError:
            page = 1
        
        ### Identify the list
        qs = self.queryset
        ### Search/filter the list
        
        ### Sort the list
        if sort_by:
            if sort_by[0] == "-":
                sort_by_raw = sort_by[1:]
            else:
                sort_by_raw = sort_by
            
            spec = self.get_column_spec(sort_by_raw)
            sort_func = spec['sort_function']
            
            if spec['sortable']:
                if sort_by_raw in [x.name for x in self.model._meta.fields] and sort_func == None:
                    qs = qs.order_by(sort_by)
                else:
                    # kinda high cpu, should be used with caution
                    if sort_func == None:
                        sort_func = cmp
                    qs = [i for i in qs]
                    qs.sort(lambda x,y:sort_func(self.get_value(request,x,sort_by_raw),self.get_value(request,y,sort_by_raw)))
                    if sort_by[0] == "-":
                        qs.reverse()
            
        ### Pagination
        paginator = Paginator(qs, self.paginate_by)

        try:
            page_obj = paginator.page(page)            
            object_list = page_obj.object_list
        except InvalidPage:
            raise Http404
        
        ### Generate the header
        vars = request.GET.copy()
        if 'sort' in vars:
            cur_sort = vars['sort']
            del vars['sort']
        else:
            cur_sort = None
            
        if len(vars.keys()) > 0:
            root_vars = "&%s" % vars.urlencode()
        else:
            root_vars = ""

        headers = []
        for col in self.columns:
            spec = self.get_column_spec(col)
            if callable(spec['header']):
                label = spec['header'](self,request,col)
            else:
                label = spec['header']
            
            if col == cur_sort:
                sort_name = '-' + col
            else:
                sort_name = col
                
            if spec['sortable']:
                link = """<a href="?sort=%s%s">%s</a>""" % (sort_name,root_vars,label)
            else:
                link = label
                
            headers.append({'column':col,
                            'label':label,
                            'link':link})
        
        
        context = self.extra_context.copy()    
        context.update({
            'headers' : headers,
            'sort':sort_by,
            'base_url':self.base_url,
        })
        
        c = RequestContext(request,context)
        
        t = loader.get_template(self.header_template)
        header = t.render(c)
        
        ### Loop over the rows
        t = loader.get_template(self.item_template)
        index = 1
        absolute_index = page_obj.start_index()
        rendered_rows = []
        for object in object_list:
            ## Loop over all the columns
            row = []
            for col in self.columns:
                raw_value = self.get_value(request,object,col)
                display_value = self.get_display_value(request,object,col)
                
                row.append({'column':col,
                            'raw':raw_value,
                            'display':display_value})
            
            context = self.extra_context.copy()    
            context.update({
                'headers' : headers,
                'sort':sort_by,
                'row':row,
                'object':object,
                'index':index,
                'absolute_index':absolute_index,
                'base_url':self.base_url,
            })
            
            c = RequestContext(request,context)
        
            rendered_rows.append(t.render(c))
            object.paginated_index = index
            object.paginated_absolute_index = absolute_index
            index += 1
            absolute_index+= 1
        t = loader.get_template(self.list_template)
        
        context = self.extra_context.copy()
        context.update({
            'header':header,
            'headers' : headers,
            'page_obj':page_obj,
            'paginator':paginator,
            'sort':sort_by,
            'object_list':object_list,
            'base_url':self.base_url,
            'rows':rendered_rows,
            'page':page,
        })
        context.update(self.populate_context(request,*args,**kwargs))
        c = RequestContext(request,context)
        
        return t.render(c)