def search(request, template="search_results.html"): """ Display search results. Takes an optional "contenttype" GET parameter in the form "app-name.ModelName" to limit search results to a single model. """ settings.use_editable() query = request.GET.get("q", "") page = request.GET.get("page", 1) per_page = settings.SEARCH_PER_PAGE max_paging_links = settings.MAX_PAGING_LINKS try: search_model = get_model(*request.GET.get("type", "").split(".", 1)) if not issubclass(search_model, Displayable): raise TypeError except (ValueError, TypeError, LookupError): search_model = Displayable search_type = _("Everything") else: search_type = search_model._meta.verbose_name_plural.capitalize() results = search_model.objects.search(query, for_user=request.user) paginated = paginate(results, page, per_page, max_paging_links) context = { "query": query, "results": paginated, "search_type": search_type } return render(request, template, context)
def search(self, *args, **kwargs): """ Proxy to queryset's search method for the manager's model and any models that subclass from this manager's model if the model is abstract. """ if not settings.SEARCH_MODEL_CHOICES: # No choices defined - build a list of leaf models (those # without subclasses) that inherit from Displayable. models = [m for m in get_models() if issubclass(m, self.model)] parents = reduce(ior, [m._meta.get_parent_list() for m in models]) models = [m for m in models if m not in parents] elif getattr(self.model._meta, "abstract", False): # When we're combining model subclasses for an abstract # model (eg Displayable), we only want to use models that # are represented by the ``SEARCH_MODEL_CHOICES`` setting. # Now this setting won't contain an exact list of models # we should use, since it can define superclass models such # as ``Page``, so we check the parent class list of each # model when determining whether a model falls within the # ``SEARCH_MODEL_CHOICES`` setting. search_choices = set([get_model(*name.split(".", 1)) for name in settings.SEARCH_MODEL_CHOICES]) models = set() parents = set() for model in get_models(): # Model is actually a subclasses of what we're # searching (eg Displayabale) is_subclass = issubclass(model, self.model) # Model satisfies the search choices list - either # there are no search choices, model is directly in # search choices, or its parent is. this_parents = set(model._meta.get_parent_list()) in_choices = not search_choices or model in search_choices in_choices = in_choices or this_parents & search_choices if is_subclass and (in_choices or not search_choices): # Add to models we'll seach. Also maintain a parent # set, used below for further refinement of models # list to search. models.add(model) parents.update(this_parents) # Strip out any models that are superclasses of models, # specifically the Page model which will generally be the # superclass for all custom content types, since if we # query the Page model as well, we will get duplicate # results. models -= parents else: models = [self.model] all_results = [] user = kwargs.pop("for_user", None) for model in models: try: queryset = model.objects.published(for_user=user) except AttributeError: queryset = model.objects.get_query_set() all_results.extend(queryset.search(*args, **kwargs)) return sorted(all_results, key=lambda r: r.result_count, reverse=True)
def initial_validation(request, prefix): """ Returns the related model instance and post data to use in the comment/rating views below. Both comments and ratings have a ``prefix_ACCOUNT_REQUIRED`` setting. If this is ``True`` and the user is unauthenticated, we store their post data in their session, and redirect to login with the view's url (also defined by the prefix arg) as the ``next`` param. We can then check the session data once they log in, and complete the action authenticated. On successful post, we pass the related object and post data back, which may have come from the session, for each of the comments and ratings view functions to deal with as needed. """ post_data = request.POST settings.use_editable() login_required_setting_name = prefix.upper() + "S_ACCOUNT_REQUIRED" posted_session_key = "unauthenticated_" + prefix redirect_url = "" if getattr(settings, login_required_setting_name, False): if not request.user.is_authenticated(): request.session[posted_session_key] = request.POST error( request, _("You must be logged in. Please log in or " "sign up to complete this action.")) redirect_url = "%s?next=%s" % (settings.LOGIN_URL, reverse(prefix)) elif posted_session_key in request.session: post_data = request.session.pop(posted_session_key) if not redirect_url: model_data = post_data.get("content_type", "").split(".", 1) if len(model_data) != 2: return HttpResponseBadRequest() try: model = get_model(*model_data) obj = model.objects.get(id=post_data.get("object_pk", None)) except (TypeError, ObjectDoesNotExist, LookupError): redirect_url = "/" if redirect_url: if request.is_ajax(): return HttpResponse(dumps({"location": redirect_url})) else: return redirect(redirect_url) return obj, post_data
def get_profile_model(): """ Returns the Mezzanine profile model, defined in settings.AUTH_PROFILE_MODULE, or None if no profile model is configured. """ if not getattr(settings, "AUTH_PROFILE_MODULE", None): raise ProfileNotConfigured try: return get_model(settings.AUTH_PROFILE_MODULE) except ValueError: raise ImproperlyConfigured("AUTH_PROFILE_MODULE must be of " "the form 'app_label.model_name'") except LookupError: raise ImproperlyConfigured("AUTH_PROFILE_MODULE refers to " "model '%s' that has not been installed" % settings.AUTH_PROFILE_MODULE)
def initial_validation(request, prefix): """ Returns the related model instance and post data to use in the comment/rating views below. Both comments and ratings have a ``prefix_ACCOUNT_REQUIRED`` setting. If this is ``True`` and the user is unauthenticated, we store their post data in their session, and redirect to login with the view's url (also defined by the prefix arg) as the ``next`` param. We can then check the session data once they log in, and complete the action authenticated. On successful post, we pass the related object and post data back, which may have come from the session, for each of the comments and ratings view functions to deal with as needed. """ post_data = request.POST settings.use_editable() login_required_setting_name = prefix.upper() + "S_ACCOUNT_REQUIRED" posted_session_key = "unauthenticated_" + prefix redirect_url = "" if getattr(settings, login_required_setting_name, False): if not request.user.is_authenticated(): request.session[posted_session_key] = request.POST error(request, _("You must be logged in. Please log in or " "sign up to complete this action.")) redirect_url = "%s?next=%s" % (settings.LOGIN_URL, reverse(prefix)) elif posted_session_key in request.session: post_data = request.session.pop(posted_session_key) if not redirect_url: model_data = post_data.get("content_type", "").split(".", 1) if len(model_data) != 2: return HttpResponseBadRequest() try: model = get_model(*model_data) obj = model.objects.get(id=post_data.get("object_pk", None)) except (TypeError, ObjectDoesNotExist, LookupError): redirect_url = "/" if redirect_url: if request.is_ajax(): return HttpResponse(dumps({"location": redirect_url})) else: return redirect(redirect_url) return obj, post_data
def edit(request): """ Process the inline editing form. """ model = get_model(request.POST["app"], request.POST["model"]) obj = model.objects.get(id=request.POST["id"]) form = get_edit_form(obj, request.POST["fields"], data=request.POST, files=request.FILES) if not (is_editable(obj, request) and has_site_permission(request.user)): response = _("Permission denied") elif form.is_valid(): form.save() model_admin = ModelAdmin(model, admin.site) message = model_admin.construct_change_message(request, form, None) model_admin.log_change(request, obj, message) response = "" else: response = list(form.errors.values())[0][0] return HttpResponse(response)
def processor_for(content_model_or_slug, exact_page=False): """ Decorator that registers the decorated function as a page processor for the given content model or slug. When a page exists that forms the prefix of custom urlpatterns in a project (eg: the blog page and app), the page will be added to the template context. Passing in ``True`` for the ``exact_page`` arg, will ensure that the page processor is not run in this situation, requiring that the loaded page object is for the exact URL currently being viewed. """ content_model = None slug = "" if isinstance(content_model_or_slug, (str, _str)): try: content_model = get_model(*content_model_or_slug.split(".", 1)) except (TypeError, ValueError, LookupError): slug = content_model_or_slug elif issubclass(content_model_or_slug, Page): content_model = content_model_or_slug else: raise TypeError( "%s is not a valid argument for page_processor, " "which should be a model subclass of Page in class " "or string form (app.model), or a valid slug" % content_model_or_slug ) def decorator(func): parts = (func, exact_page) if content_model: model_name = content_model._meta.object_name.lower() processors[model_name].insert(0, parts) else: processors["slug:%s" % slug].insert(0, parts) return func return decorator
def search(request, template="search_results.html"): """ Display search results. Takes an optional "contenttype" GET parameter in the form "app-name.ModelName" to limit search results to a single model. """ settings.use_editable() query = request.GET.get("q", "") page = request.GET.get("page", 1) per_page = settings.SEARCH_PER_PAGE max_paging_links = settings.MAX_PAGING_LINKS try: search_model = get_model(*request.GET.get("type", "").split(".", 1)) search_model.objects.search # Attribute check except (ValueError, TypeError, LookupError, AttributeError): search_model = Displayable search_type = _("Everything") else: search_type = search_model._meta.verbose_name_plural.capitalize() results = search_model.objects.search(query, for_user=request.user) paginated = paginate(results, page, per_page, max_paging_links) context = {"query": query, "results": paginated, "search_type": search_type} return render(request, template, context)
def processor_for(content_model_or_slug, exact_page=False): """ Decorator that registers the decorated function as a page processor for the given content model or slug. When a page exists that forms the prefix of custom urlpatterns in a project (eg: the blog page and app), the page will be added to the template context. Passing in ``True`` for the ``exact_page`` arg, will ensure that the page processor is not run in this situation, requiring that the loaded page object is for the exact URL currently being viewed. """ content_model = None slug = "" if isinstance(content_model_or_slug, (str, _str)): try: content_model = get_model(*content_model_or_slug.split(".", 1)) except (TypeError, ValueError, LookupError): slug = content_model_or_slug elif issubclass(content_model_or_slug, Page): content_model = content_model_or_slug else: raise TypeError("%s is not a valid argument for page_processor, " "which should be a model subclass of Page in class " "or string form (app.model), or a valid slug" % content_model_or_slug) def decorator(func): parts = (func, exact_page) if content_model: model_name = content_model._meta.object_name.lower() processors[model_name].insert(0, parts) else: processors["slug:%s" % slug].insert(0, parts) return func return decorator