def post(self, request, *args, **kwargs): try: category = shop_models.ProductCategories.objects.get(pk=kwargs.pop("category_id")) except shop_models.Product.DoesNotExist: raise http.Http404("No category matches the given query.") form = shop_forms.ProductCategoryForm(request.POST, instance=category) if form.is_valid(): category_data = form.save(commit=False) #Modelform category_data.parent_slug = category_data.parent.slug category_data.save() messages.success(request, 'Save successful..') return shortcuts.redirect("admin_shop_categories") else: messages.error(request, 'category not saved..') return render(request, "admin/shop/categories_edit.html",{ 'formbundle':[ ("Category details",form),] })
def get_object(self): # We allow superusers to force an order thank-you page for testing order = None if self.request.user.is_superuser: if 'order_number' in self.request.GET: order = Order._default_manager.get( number=self.request.GET['order_number']) elif 'order_id' in self.request.GET: order = Order._default_manager.get( id=self.request.GET['order_id']) if not order: if 'checkout_order_id' in self.request.session: order = Order._default_manager.get( pk=self.request.session['checkout_order_id']) else: raise http.Http404(_("No order found")) return order
def root(self, request, url): """ Handles main URL routing for the admin app. `url` is the remainder of the URL -- e.g. 'comments/comment/'. """ if request.method == 'GET' and not request.path.endswith('/'): return http.HttpResponseRedirect(request.path + '/') # Figure out the admin base URL path and stash it for later use self.root_path = re.sub(re.escape(url) + '$', '', request.path) url = url.rstrip('/') # Trim trailing slash, if it exists. # The 'logout' view doesn't require that the person is logged in. if url == 'logout': return self.logout(request) # Check permission to continue or display login form. if not self.has_permission(request): return self.login(request) if url == '': return self.index(request) elif url == 'password_change': return self.password_change(request) elif url == 'password_change/done': return self.password_change_done(request) elif url == 'jsi18n': return self.i18n_javascript(request) # urls starting with 'r/' are for the "show in web" links elif url.startswith('r/'): from django.views.defaults import shortcut return shortcut(request, *url.split('/')[1:]) else: match = USER_CHANGE_PASSWORD_URL_RE.match(url) if match: return self.user_change_password(request, match.group(1)) if '/' in url: return self.model_page(request, *url.split('/', 2)) raise http.Http404('The requested admin page does not exist.')
def root(self, request, url): """ Handles main URL routing for the databrowse app. `url` is the remainder of the URL -- e.g. 'objects/3'. """ # Delegate to the appropriate method, based on the URL. if url is None: return self.main_view(request) try: plugin_name, rest_of_url = url.split('/', 1) except ValueError: # need more than 1 value to unpack plugin_name, rest_of_url = url, None try: plugin = self.plugins[plugin_name] except KeyError: raise http.Http404( 'A plugin with the requested name does not exist.') return plugin.model_view(request, self, rest_of_url)
def version_detail(request, addon, version_num): # TODO: Does setting this in memcachd even make sense? # This is specific to an add-ons version so the chance of this hitting # the cache and not missing seems quite bad to me (cgrebs) def _fetch(): qs = _version_list_qs(addon) return list(qs.values_list('version', flat=True)) ids = cache_get_or_set( u'version-detail:{}:{}'.format(addon.id, version_num), _fetch) url = reverse('addons.versions', args=[addon.slug]) if version_num in ids: page = 1 + ids.index(version_num) / PER_PAGE to = urlparams(url, 'version-%s' % version_num, page=page) return http.HttpResponseRedirect(to) else: raise http.Http404()
def delete_invite(request, invite_pk): """Delete an invite to join a group.""" invite = get_object_or_404(Invite, pk=invite_pk) group = invite.group if (group.curators.filter(id=request.user.userprofile.id).exists() or request.user.userprofile.is_manager): redeemer = invite.redeemer invite.delete() notify_redeemer_invitation_invalid.delay(redeemer.pk, group.pk) msg = _(u'The invitation to {0} has been successfully revoked.' ).format(redeemer) messages.success(request, msg) next_section = request.GET.get('next') next_url = urlparams(reverse('groups:group_edit', args=[group.url]), next_section) return http.HttpResponseRedirect(next_url) raise http.Http404()
def t_shirt(request): if not waffle.switch_is_active('t-shirt-orders'): raise http.Http404() user = request.user eligible = tshirt_eligible(user) if request.method == 'POST': if not eligible: messages.error(request, _("We're sorry, but you are not eligible to " "request a t-shirt at this time.")) return redirect('users.t-shirt') if not user.t_shirt_requested: user.update(t_shirt_requested=datetime.now()) return render(request, 'users/t-shirt.html', {'eligible': eligible, 'user': user})
def download_source(request, version_id): version = get_object_or_404(Version.objects, pk=version_id) # General case: version is listed. if version.channel == amo.RELEASE_CHANNEL_LISTED: if not (version.source and (acl.check_addon_ownership( request, version.addon, viewer=True, ignore_disabled=True))): raise http.Http404() else: if not owner_or_unlisted_reviewer(request, version.addon): raise http.Http404 # Not listed, not owner or unlisted reviewer. res = HttpResponseSendFile(request, version.source.path) path = version.source.path if not isinstance(path, unicode): path = path.decode('utf8') name = os.path.basename(path.replace(u'"', u'')) disposition = u'attachment; filename="{0}"'.format(name).encode('utf8') res['Content-Disposition'] = disposition return res
def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) hashvalue = self.kwargs['hash'] if not arm.Seat.exists(hashvalue): raise djh.Http404() seat = arm.Seat.by_hash(hashvalue) ctx['seat'] = seat ctx['room'] = seat.room ctx['settings'] = settings retention_3g = settings.DATA_RETENTION_DAYS_STATUS_3G if settings.USE_STATUS_3G_FIELD and \ retention_3g <= settings.DATA_RETENTION_DAYS: ctx['status_3g_stmt_de'] = ("Der 3G-Status wird bereits nach %d Tagen gelöscht." % retention_3g) ctx['status_3g_stmt_en'] = ("The vaccination status will be deleted after %d days." % retention_3g) else: ctx['status_3g_stmt_de'] = ctx['status_3g_stmt_en'] = "" return ctx
def review_list(request, addon, review_id=None, user_id=None, template=None): q = (Review.objects.valid().filter(addon=addon).order_by('-created')) ctx = {'addon': addon, 'grouped_ratings': GroupedRating.get(addon.id)} ctx['form'] = forms.ReviewForm(None) if review_id is not None: ctx['page'] = 'detail' # If this is a dev reply, find the first msg for context. review = get_object_or_404(Review.objects.all(), pk=review_id) if review.reply_to_id: review_id = review.reply_to_id ctx['reply'] = review q = q.filter(pk=review_id) elif user_id is not None: ctx['page'] = 'user' q = q.filter(user=user_id) if not q: raise http.Http404() else: ctx['page'] = 'list' q = q.filter(is_latest=True) ctx['reviews'] = reviews = amo.utils.paginate(request, q) ctx['replies'] = Review.get_replies(reviews.object_list) if request.user.is_authenticated(): ctx['review_perms'] = { 'is_admin': acl.action_allowed(request, 'Addons', 'Edit'), 'is_editor': acl.check_reviewer(request), 'is_author': acl.check_addon_ownership(request, addon, viewer=True, dev=True, support=True), } ctx['flags'] = get_flags(request, reviews.object_list) else: ctx['review_perms'] = {} return render(request, template, ctx)
def secure_media(request, path): if not (request.user.is_superuser or request.user.groups.filter( name__in=('sim_report', 'hotel_report')).exists()): fname = os.path.splitext(os.path.basename(path))[0] if fname.rsplit('-', 1)[0] != request.user.username: return http.HttpResponseForbidden() fpath = settings.SECURE_STORAGE.path(path) guessed = mimetypes.guess_type(fpath) try: r = http.HttpResponse(file(fpath), mimetype=guessed[0]) r['Content-Length'] = os.path.getsize(fpath) if guessed[1]: r['Content-Encoding'] = guessed[1] return r except IOError, e: if e.errno == 2: raise http.Http404() else: raise
def get_comments(request, model_slug, object_id): try: model = COMMENTABLE_MODELS[model_slug] except KeyError: raise http.Http404("no such registered model %s" % model_slug) obj = get_object_or_404(model, pk=object_id) comment_set = Comment.visible.get_comments(obj) comments_group = itertools.groupby( (c.get_dict() for c in comment_set.order_by('selector', 'created')), lambda c: c["selector"]) comments_dict = dict((k, list(v)) for k, v in comments_group) return http.JsonResponse({ "content": comments_dict, })
def download_latest(request, addon, type='xpi', platform=None): """ Download file from 'current' (latest public listed) version for an add-on. Requires same permissions as download_file() does for this file. """ platforms = [amo.PLATFORM_ALL.id] if platform is not None and int(platform) in amo.PLATFORMS: platforms.append(int(platform)) version = addon._current_version_id files = File.objects.filter(platform__in=platforms, version=version) try: # If there's a file matching our platform, it'll float to the end. file_ = sorted(files, key=lambda f: f.platform == platforms[-1])[-1] except IndexError: raise http.Http404() return download_file(request, file_.id, type=type, file_=file_, addon=addon)
def get_blob_digest(self, name, uuid, hash_method="sha256"): """ 计算 Blob 的 Digest值 :param name: :param uuid: :param hash_method: :return: """ hash_func = { "sha256": hashlib.sha256, "sha1": hashlib.sha1 }[hash_method]() file_name = self.path_spec.get_upload_path(name, uuid) if not os.path.exists(file_name): raise http.Http404() with open(file_name, "rb") as f2: for chunk in iter(lambda: f2.read(4096), b''): hash_func.update(chunk) return hash_func.hexdigest()
def download_source(request, version_id): """ Download source code for a given version_id. Requires developer of the add-on or admin reviewer permission. If the version or add-on is deleted, developers can't access. If the version source code wasn't provided, but the user had the right permissions, a 404 is raised. """ # Include deleted versions in the queryset, we'll check for that below. version = get_object_or_404(Version.unfiltered, pk=version_id) addon = version.addon # Channel doesn't matter, source code is only available to admin reviewers # or developers of the add-on. If the add-on, version or file is deleted or # disabled, then only admins can access. has_permission = acl.action_allowed(request, amo.permissions.REVIEWS_ADMIN) if ( addon.status != amo.STATUS_DISABLED and not version.files.filter(status=amo.STATUS_DISABLED).exists() and not version.deleted and not addon.is_deleted ): # Don't rely on 'admin' parameter for check_addon_ownership(), it # doesn't check the permission we want to check. has_permission = has_permission or acl.check_addon_ownership( request, addon, admin=False, dev=True ) if not has_permission: raise http.Http404() response = HttpResponseXSendFile(request, version.source.path) path = version.source.path if not isinstance(path, str): path = path.decode('utf8') name = os.path.basename(path.replace('"', '')) disposition = 'attachment; filename="{0}"'.format(name).encode('utf8') response['Content-Disposition'] = disposition response['Access-Control-Allow-Origin'] = '*' return response
def query(request, *, model_name, fields="", media): if media.startswith("profile") or media.startswith("pstats"): if "_" in media: prof_media, media = media.split("_") else: prof_media = media media = "json" profiler = cProfile.Profile() try: profiler.enable() query = Query.from_request(model_name, fields, request.GET) for x in _data_response(request, query, media, privileged=True): pass profiler.disable() if prof_media == "profile": buffer = io.StringIO() stats = pstats.Stats(profiler, stream=buffer) stats.sort_stats("cumulative").print_stats(50) stats.sort_stats("time").print_stats(50) buffer.seek(0) return HttpResponse(buffer, content_type="text/plain") elif prof_media == "pstats": buffer = io.BytesIO() marshal.dump(pstats.Stats(profiler).stats, buffer) buffer.seek(0) response = HttpResponse(buffer, content_type="application/octet-stream") response[ "Content-Disposition" ] = f"attachment; filename={query.model_name}-{timezone.now().isoformat()}.pstats" return response else: raise http.Http404(f"Bad file format {prof_media} requested") finally: if profiler: # pragma: no branch profiler.disable() else: query = Query.from_request(model_name, fields, request.GET) return _data_response(request, query, media, privileged=True)
def get(self, request, *args, **kwargs): session_cart_to_database(request) accessibles = Organization.objects.accessible_by(request.user) count = accessibles.count() next_url = self.get_redirect_url(*args, **kwargs) if next_url: create_url = '%s?next=%s' % (reverse('saas_organization_create'), next_url) else: create_url = reverse('saas_organization_create') if count == 0: if self.explicit_create_on_none: return http.HttpResponseRedirect(create_url) if self.get_implicit_create_on_none(): try: kwargs.update({ self.slug_url_kwarg: str(self.create_organization_from_user(request.user)) }) return super(OrganizationRedirectView, self).get(request, *args, **kwargs) except IntegrityError: LOGGER.warning("tried to implicitely create"\ " an organization that already exists.", extra={'request': request}) raise http.Http404("No organizations are accessible by user.") if count == 1 and not self.create_more: organization = accessibles.get() kwargs.update({self.slug_url_kwarg: accessibles.get()}) return super(OrganizationRedirectView, self).get(request, *args, **kwargs) redirects = [] for organization in accessibles: kwargs.update({self.slug_url_kwarg: organization}) url = super(OrganizationRedirectView, self).get_redirect_url(*args, **kwargs) redirects += [(url, organization.printable_name, organization.slug) ] context = self.get_context_data(**kwargs) context.update({'redirects': redirects}) self.update_context_urls(context, {'organization_create': create_url}) return self.render_to_response(context)
def _get_record(self, uuid, is_public): # if a public view, the uuid is that of a ProgramCertRecord, # if private, the uuid is that of a Program if is_public: program_cert_record = get_object_or_404(ProgramCertRecord, uuid=uuid) user = program_cert_record.user program_uuid = program_cert_record.program.uuid else: user = self.request.user program_uuid = uuid data = get_record_data( user, program_uuid, self.request.site, platform_name=self.request.site.siteconfiguration.platform_name ) # Only allow superusers to view a record with no data in it (i.e. don't allow learners to guess URLs and view) if not self.request.user.is_superuser and data["program"]["empty"]: raise http.Http404() return data
def delete_detail(self, request, **kwargs): bundle = Bundle(request=request) try: # call our obj_delete, storing the deleted_obj we returned # del_obj = CombinedTransaction.objects.get(id=kwargs['pk']) deleted_obj = self.obj_delete( bundle=bundle, **self.remove_api_resource_names(kwargs)) # build a new bundle with the deleted obj and return it in a response deleted_bundle = self.build_bundle(obj=deleted_obj, request=request) # deleted_bundle = self.full_dehydrate() # deleted_bundle = self.alter_detail_data_to_serialize(request, deleted_bundle) return self.create_response(request, deleted_bundle, response_class=http.HttpResponse) except NotFound: return http.Http404()
def post(self, request, *args, **kwargs): try: vendor = shop_models.Vendors.objects.get(pk=kwargs.pop("vendor_id")) vendor_address = shop_models.VendorAddress.objects.filter(vendor=vendor).first() except shop_models.Vendors.DoesNotExist: raise http.Http404("No 'vendor' matches the given query.") form = shop_forms.VendorForm(request.POST, instance = vendor) address_form = shop_forms.AddressForm(request.POST, instance = vendor_address.addr) if form.is_valid() and address_form.is_valid(): vendor = form.save() addr = address_form.save() messages.success(request, 'Save successful..') return shortcuts.redirect("admin_shop_vendors") else: messages.error(request, 'Vendor not saved..') return render(request, "admin/shop/vendors_edit.html",{ 'formbundle':[ ("Vendor details",form), ("Vendor address",vendor_address_form),] })
def download_file(request, file_id, type=None): file = get_object_or_404(File.objects, pk=file_id) addon = get_object_or_404(Addon.objects, pk=file.version.addon_id) if addon.is_disabled or file.status == amo.STATUS_DISABLED: if (acl.check_addon_ownership( request, addon, viewer=True, ignore_disabled=True) or acl.check_addons_reviewer(request)): return HttpResponseSendFile(request, file.guarded_file_path, content_type='application/xp-install') else: raise http.Http404() attachment = (type == 'attachment' or not request.APP.browser) loc = file.get_mirror(addon, attachment=attachment) response = http.HttpResponseRedirect(loc) response['X-Target-Digest'] = file.hash return response
def developers(request, addon, page): if addon.is_persona(): raise http.Http404() if 'src' in request.GET: contribution_src = src = request.GET['src'] else: page_srcs = { 'developers': ('developers', 'meet-developers'), 'installed': ('meet-the-developer-post-install', 'post-download'), 'roadblock': ('meetthedeveloper_roadblock', 'roadblock'), } # Download src and contribution_src are different. src, contribution_src = page_srcs.get(page) return render( request, 'addons/impala/developers.html', { 'addon': addon, 'page': page, 'src': src, 'contribution_src': contribution_src })
def __init__(self, repo, course, flow_id, participation=None): # type: (Repo_ish, Course, Text, Optional[Participation]) -> None """*participation* and *flow_session* are not stored and only used to figure out versioning of the flow content. """ self.repo = repo self.course = course self.flow_id = flow_id from django.core.exceptions import ObjectDoesNotExist self.course_commit_sha = get_course_commit_sha(self.course, participation) try: self.flow_desc = get_flow_desc(self.repo, self.course, flow_id, self.course_commit_sha) except ObjectDoesNotExist: raise http.Http404()
def post(self, request, *args, **kwargs): if request.user.is_superuser: qs = models.Shipment.objects.filter() else: qs = models.Shipment.objects.filter(project=self.request.user) try: shipment = qs.get(pk=self.kwargs['pk']) samples = json.loads(request.POST.get('samples', '[]')) grouped_samples = defaultdict(list) loc_info = { container.pk: dict(container.kind.locations.values_list('name', 'pk')) for container in shipment.containers.all() } for sample in sorted(samples, key=itemgetter('container', 'location')): grouped_samples[sample['group']].append({ 'project': shipment.project, 'container_id': sample['container'], 'location_id': sample.get('location') and loc_info[sample['container']][str(sample['location'])] or None }) to_create = [] models.Sample.objects.filter(container__shipment=shipment).delete() for group in shipment.groups.all(): # remove existing samples for i, details in enumerate(grouped_samples.get(group.pk, [])): to_create.append( models.Sample(name='{}_{}'.format(group.name, i + 1), group=group, **details)) shipment.project.samples.bulk_create(to_create) return JsonResponse({'url': shipment.get_absolute_url()}, safe=False) except models.Shipment.DoesNotExist: raise http.Http404('Shipment Not Found!')
def process_exception(self, request, exception): """Catches internal Horizon exception classes. Exception classes such as NotAuthorized, NotFound and Http302 are caught and handles them gracefully. """ if isinstance(exception, (exceptions.NotAuthorized, exceptions.NotAuthenticated)): auth_url = settings.LOGIN_URL next_url = iri_to_uri(request.get_full_path()) if next_url != auth_url: field_name = REDIRECT_FIELD_NAME else: field_name = None login_url = request.build_absolute_uri(auth_url) response = redirect_to_login(next_url, login_url=login_url, redirect_field_name=field_name) if isinstance(exception, exceptions.NotAuthorized): logout_reason = _("Unauthorized. Please try logging in again.") utils.add_logout_reason(request, response, logout_reason, 'error') # delete messages, created in get_data() method # since we are going to redirect user to the login page response.delete_cookie('messages') if request.is_ajax(): response_401 = http.HttpResponse(status=401) response_401['X-Horizon-Location'] = response['location'] return response_401 return response # If an internal "NotFound" error gets this far, return a real 404. if isinstance(exception, exceptions.NotFound): raise http.Http404(exception) if isinstance(exception, exceptions.Http302): # TODO(gabriel): Find a way to display an appropriate message to # the user *on* the login form... return shortcuts.redirect(exception.location)
def serve_action( request: http.HttpRequest, action_id: int, ) -> http.HttpResponse: """Serve the rendering of an action in a workflow for a given user. - uatn: User attribute name. The attribute to check for authentication. By default this will be "email". - uatv: User attribute value. The value to check with respect to the previous attribute. The default is the user attached to the request. If the two last parameters are given, the authentication is done as: user_record[user_attribute_name] == user_attribute_value :param request: Http Request :param action_id: Action ID to use :return: Http response """ # Get the action object action = models.Action.objects.filter(pk=int(action_id)).prefetch_related( 'conditions', ).first() if not action or (not action.serve_enabled) or (not action.is_active): raise http.Http404 # Get the parameters user_attribute_name = request.GET.get('uatn', 'email') if user_attribute_name not in action.workflow.get_column_names(): raise http.Http404 if action.is_out: try: response = services.serve_action_out(request.user, action, user_attribute_name) except Exception: raise http.Http404() return response return _common_run_survey_row(request, action, user_attribute_name)
def confirm_member(request, url, user_pk): """ Add a member to a group who has requested membership. """ group = get_object_or_404(Group, url=url) profile = get_object_or_404(UserProfile, pk=user_pk) is_curator = (request.user.userprofile in group.curators.all()) is_manager = request.user.userprofile.is_manager group_url = reverse('groups:show_group', args=[group.url]) # Workaround for using both request.GET and request.POST data next_url = getattr(request, request.method).get('next_url', group_url) if not (is_curator or is_manager): raise http.Http404() try: membership = GroupMembership.objects.get(group=group, userprofile=profile) except GroupMembership.DoesNotExist: messages.error( request, _('This user has not requested membership in this group.')) else: if membership.status == GroupMembership.MEMBER and not membership.needs_renewal: messages.error(request, _('This user is already a member of this group.')) else: status = GroupMembership.MEMBER if group.terms: status = GroupMembership.PENDING_TERMS group.add_member(profile, status=status, inviter=request.user.userprofile) if membership.needs_renewal: messages.info( request, _('The membership of the user has been renewed.')) else: messages.info( request, _('This user has been added as a member of this group.')) return redirect(next_url)
def review_list(request, addon, review_id=None, user_id=None, rating=None): qs = Review.objects.valid().filter(addon=addon).order_by('-created') ctx = {'product': addon, 'score': rating, 'review_perms': {}} if review_id is not None: qs = qs.filter(pk=review_id) ctx['page'] = 'detail' # If this is a dev reply, find the first msg for context. review = get_object_or_404(Review, pk=review_id) if review.reply_to_id: review_id = review.reply_to_id ctx['reply'] = review elif user_id is not None: qs = qs.filter(user=user_id) ctx['page'] = 'user' if not qs: raise http.Http404() else: ctx['page'] = 'list' qs = qs.filter(is_latest=True) ctx['ratings'] = ratings = amo.utils.paginate(request, qs, 20) if not ctx.get('reply'): ctx['replies'] = Review.get_replies(ratings.object_list) if request.user.is_authenticated(): ctx['review_perms'] = { 'is_admin': acl.action_allowed(request, 'Addons', 'Edit'), 'is_editor': acl.check_reviewer(request), 'is_author': acl.check_addon_ownership(request, addon, viewer=True, dev=True, support=True), } ctx['flags'] = get_flags(request, ratings.object_list) ctx['has_review'] = addon.reviews.filter(user=request.user.id).exists() return jingo.render(request, 'ratings/listing.html', ctx)
def podcasts_data(request): context = {} search_term = request.GET.get("search", "").strip() search = PodcastDoc.search() if search_term: search = search.query("match_phrase", name=search_term) search = search.sort("-times_picked", "_score") page = request.GET.get("page", 1) page_index = int(page) - 1 assert page_index >= 0, page_index batch_size = 15 if page_index > 0: # need to check that it's not out of bounds response = PodcastDoc.search().execute() if batch_size * (1 + page_index) > response.hits.total: raise http.Http404("Page too big") search = search[page_index * batch_size : (page_index + 1) * batch_size] response = search.execute() context["count"] = response.hits.total items = [] for hit in response.hits: items.append(hit.to_dict()) context["items"] = items pagination = { "has_previous": page_index > 0, "has_next": (page_index + 1) * batch_size < context["count"], "number": page_index + 1, "num_pages": math.ceil(context["count"] / batch_size), } if pagination["has_previous"]: pagination["previous_page_number"] = page_index if pagination["has_next"]: pagination["next_page_number"] = page_index + 2 context["pagination"] = pagination return http.JsonResponse(context)
def app_index(self, request, app_label, extra_context=None): user = request.user has_module_perms = user.has_module_perms(app_label) app_dict = {} for model, model_admin in self._registry.items(): if app_label == model._meta.app_label: if has_module_perms: perms = { 'add': user.has_perm("%s.%s" % (app_label, model._meta.get_add_permission())), 'change': user.has_perm("%s.%s" % (app_label, model._meta.get_change_permission())), 'delete': user.has_perm("%s.%s" % (app_label, model._meta.get_delete_permission())), } # Check whether user has any perm for this module. # If so, add the module to the model_list. if True in perms.values(): model_dict = { 'name': capfirst(model._meta.verbose_name_plural), 'admin_url': '%s/' % model.__name__.lower(), 'perms': perms, } if app_dict: app_dict['models'].append(model_dict), else: app_dict = { 'name': app_label.title(), 'app_url': '', 'has_module_perms': has_module_perms, 'models': [model_dict], } if not app_dict: raise http.Http404('The requested admin page does not exist.') # Sort the models alphabetically within each app. app_dict['models'].sort(lambda x, y: cmp(x['name'], y['name'])) context = { 'title': _('%s administration' % capfirst(app_label)), 'app_list': [app_dict] } context.update(extra_context or {}) return render_to_response(self.app_index_template or 'admin/app_index.html', context, context_instance=template.RequestContext(request) )