wagtail main search add modelAdmin models - python

Quick question on wagtail's main search at the top of the left sidebar beneath the logo.
By default that search box searches pages, images, documents, users.
Two questions:
Is there a way to modify that search scope so it also includes modelAdmin models?
Is there a way to remove pages from the search query list so it only searches images, documents, users?
I can't seem to find anything in the docs about it. I know you can search modelAdmin models once on the model admin list view, I have that working. I was just looking for a way to extend that search to be included on the main sidebar search as well.
Any direction you can provide would be much appreciated.

The admin search area does show multiple items, such as pages, images, documents etc.
However, this page only searches page models, when you click the other models (e.g. images), it will take you to the images search page, it will also append the query param q based on any existing search.
So just to clarify, this page only searches pages and to search for other items, it takes you elsewhere in the Wagtail admin.
Hopefully the below answers your specific scenario questions.
1. Modify the admin/pages search scope or results
This could possibly be done by making your own view, but it is not simple
You can see the search view function here https://github.com/wagtail/wagtail/blob/master/wagtail/admin/views/pages.py#L958
You can redirect any URL by modifying your urls.py to direct the admin/pages/search/ page to your custom view.
However, you would likely need to re-write (copy/paste) most of the view as it is a function, not class view
2. Adding custom search areas
This can be done by the register_admin_search_area hook, it will add (in a custom order) an item next to the 'other searches' text
See documentation here https://docs.wagtail.io/en/latest/reference/hooks.html#register-admin-search-area
This lets you add what is essentially a link to another search area elsewhere in the Wagtail admin (code example below)
3. Removing a search area
The simplest way to hide one of the items in the 'other searches' list would be with a CSS change
The next best way would be to customise the template wagtail/admin/templates/wagtailadmin/shared/search_other.html with an override and then filter the results
I am not aware of a way to remove hooks or registered hooks without some monkey patching, but the hooks get collected and stored as admin_search_areas you can see the code here - https://github.com/wagtail/wagtail/blob/master/wagtail/admin/search.py#L102
Example Code for using the register_admin_search_area hook
This basically uses the documentation example but gives you a rough idea of how to go to a specific ModelAdmin index view using this feature. Note: this does not search ALL ModelAdmin models, only one specific one.
You can always make a custom search page for searching all models at once though.
from wagtail.core import hooks
from wagtail.admin.search import SearchArea
# ...
#hooks.register('register_admin_search_area')
def register_model_admin_search_area():
# PeopleModelAdmin is a ModelAdmin also in the same hooks file
index_url = PeopleModelAdmin().url_helper.index_url
return SearchArea(
'People ModelAdmin',
index_url,
classnames='icon icon-user',
order=10000
)
#hooks.register('register_admin_search_area')
def register_snippets_search_area():
url = reverse('wagtailsnippets:list', args=('base', 'people'))
return SearchArea(
'People Snippets',
url,
classnames='icon icon-user',
order=10000
)

Related

How can I add a changeable "subfield" to a ModelField in django?

I'm trying to create a kind of "subfield" for a CharField in django, but I'm not sure (a) if it is possible at all and (b) how to succeed if it is indeed possible.
Let's say I want a model for Tools. They would have a, e.g., a field for long_name, short_name, maybe a ForeignKey for realizing different departments. One of these tools I'd like to be a Link, the said "subfield" being a URLField with the href to the webpage.
Now, I can create multiple link entries with the associated URL, but I'd rather have only one tool called "Link" with the changing URL attached. Is this a case for ForeignKey as well? Does it make sense to have a model with only one field (well, two if you count the pkid) in it?
Or am I on a completely lost path here?
If I've understood you correctly, you want to have a number of links that can be attached to a Tool model, so instead of just having a single URLField you would have a Many-to-One relation with a Link model:
class ToolLink(models.Model):
url = models.URLField(...
class Tool(models.Model):
links = models.ForeignKey(ToolLink, ...
The problem is that you only want one particular tool to be able to hold links. Your options are to create a 'Tool' base model that then has multiple different types of tool, like 'StandardTool', 'LinkTool', etc. or to setup some logic that monitors whether the Tool has links or not (or if another tool already has links) and whether creating links is acceptable.

Wagtail large list within stream field block

We use wagtail for our blogs that are part of an eCommerce site. When we want to add a product to the blog as it stands we have to put the exact product name in which then matches on save. As names can change this then breaks that blog which isnt ideal.
What we would like to do is add a field to our streamfield block that lets you pick from our list of products, however as we have 200k+ products and there might be up to 20 products on each blog loading the list into a dropdown is no good. What we need is to replicate what we do in Django admin using django-autocomplete-light where you start typing and get results based on that rather than loading the list into the HTML.
What we cant work out is how to do that within a streamfield block, I have seen libraries like "Wagtail Autocomplete" however it seems you can only use that as a panel rather than within a block. As far as we can see you can only use sub-classes of wagtail.core.blocks or they dont show up in the interface.
Any ideas?
Thanks in advance!
You can extend the editor. Although the examples are mainly focussed on adding CSS style, it still should be possible. You can read more on this at the documentation: http://docs.wagtail.io/en/v2.8/advanced_topics/customisation/extending_draftail.html#
Another option would be is to use the Wagtail autocomplete panel for specifying the product you need to reference to, in a seperate field of course. Then, using a regular f-string replacement, place the proper product details in the text.

The responseMessages is not displaying in Django-Swagger integration

I am using DRF YASG to document my API.
I want to remove calls for PUT and PATCH from here. For the views here I have used viewsets.ModelViewSet.
Another app uses APIview for its views.py. How can I exclude methods for a particular url.
My view contains two methods POST and DELETE. But for implementing the methods I have seperate URLs.
The problem is that both the URLs show both methods and the list just gets too big.
The question might be similar but I have a constraint of not making changes in the previous code-base.

How do you add a new entry into the django admin index?

I'm working on a Django project, and I've created some custom admin views using the get_urls override method described in the documentation. It works perfectly. There is just one problem. There is no way to get to this custom admin view unless you already know the URL.
There are some ways I already know of to add a link to this view somewhere in the admin, but none of them are satisfactory. I want a link to the custom view to appear in the model listings right with all the model admins. I just don't want it to have +add or +change links next to it because it isn't a model.
I could just override the admin_site or the template, but this is no good. It puts the customization on the project level instead of the app level. It also will only put the link on the /admin/ page and not the /admin/myapp/ page.
I could also just easily add the link in a different location by overriding the app_index.html template, but that is not exactly a convenient or intuitive place to look for it.
Another solution I came up with is to create a blank model and register a blank admin for it. Then steal the url patterns for that model so clicking on its entry goes to my custom view instead of to a blank add/change view. That works, but it's an incredibly ugly hack.
Here is a picture of what I'm trying to achieve.
I still think the correct way of doing this is overwriting some parts of django admin templates. There is no easy way of adding these links.
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template
I also found this article http://coffeeonthekeyboard.com/o-hai-django-adminplus-568/ which also suggests that django-adminplus is a good tool for doing this. Personally I prefer to keep clear of any extra dependancies and would still use templates - but thats up to you.
Have you tried this app: https://github.com/jsocol/django-adminplus? Even if it does not work for the exact purpose you are trying to achieve, at least it can give you some enlightement by checking out the code
You need to override the template admin/index.html. Thenput a new pair of tags after the {% endfor %} on line 40.
You might also be able to solve it using jQuery.

In Django, searching and filter by searchbox and categories in one go?

I wonder if you could help me.
I have a list of data that will be displayed on one page. There is a simple search box, a list of categories and a list of tags that can all be used to filter the list of data. I'm trying to built it from the ground up (so it doesn't require JavaScript) but eventually it will submit the search criteria and return back a new list using Ajax.
So I have a list of categories in my database ('large', 'small', etc), and I have a list of tags in my database ('wooden', 'brass'). Tags are used to filter down more of what's in the categories. I then have a search box. Ideally, I want the user to effectively tick which categories they want, tick what tags they want and possibly put a search for keywords, and then submit all of that data so it can be queried and a new list of the filtered data can be returned.
I'm not a Django expert, and I'm stuck on how and where to do this... What is the Django way of spitting out the categories as a checkbox list, the tags as a checkbox list and the search box with a submit button... Which when submitted, I can take all that data and do the necessary queries on the database? I don't quite understand how I'd do this... I've been looking at the Django Docs and the Django Book for a few days and the way I'm doing things doesn't seem to be listed.
Please, any help at all would be fantastic.
spitting out the categories as a checkbox list,
the tags as a checkbox list and the
search box with a submit button...
This is a <form> in your HTML page. It probably doesn't match anything in the Django model very well. It's a unique form built more-or-less manually.
I can take all that data and do the necessary queries on the database?
That's a view function.
You'll probably have something like this.
objects= SomeModel.objects
if request.GET ... has categories ...
objects = objects.filter( ... categories ... )
if request.GET ... has tags ...
objects = objects.filter( ... tags ... )
if request.GET ... has search ...
objects = objects.filter( something__contains( search ) )
return render_to_response( ... etc. ... )
the way I'm doing things doesn't seem to be listed.
You're beyond the tutorial here.
What to do?
Do the ENTIRE tutorial. All the way through. Every step. It doesn't seem like it solves your problem, but you MUST do the ENTIRE tutorial.
Design your model. You didn't mention the model in the question. It's the absolutely most important and fundamental thing.
Create the default admin interface for that model. Get the default admin interface to work and do the kinds of things you'd like to do. It has great search, category and tag filtering.
In order to get the default admin to work, you'll need to design fairly sophisticated model and form features. You'll probably have to add method functions to your model as well as choice items and other goodness.
AFTER you have the admin page pretty close to what you want, you can write you own customized view.
each single checkbox has a different name ('category_option_1', 'category_option_2', etc.) ... How do I read these? I can't just put request.POST['category_option_n']?
Really? Why didn't your question say that?
Are you asking about this?
for k in range(1024):
name = 'category_option_{0}'.format(k)
# Use request.POST.get(name,None) to build a `Q` object

Categories