Django + Haystack how to do this search - django

I'm new to Haystack and to the search world so I didn't know how to ask this question.
What I want to achieve is the following.
Having a search query like: one two
I would like to get returned any content like:
This one
one
two
two one
something one here
Is this possible with Haystack + solr/xapian?
Is also possible to have a relevance on the result? In the case where both words are hit, that would give more relevance to me.
I'm currently using SearchQuerySet in my view but can't achieve that.
Cheers

So you're basically looking for an OR type query right? By default haystack uses an AND operation for joining queries.
You can do this two ways:
Change HAYSTACK_DEFAULT_OPERATOR within your settings.py to be OR. This will obviously be a site-wide change.
Modify your SearchQuerySet form to use filter_or which will force the OR style lookup. So pass a new one into your form/view: SearchQuerySet.filter_or(**kwargs)
Apart from that, you could always join Django Q objects together but considering you have these options, those are probably your best bet.
For relevance, you should read the Best Practices page which goes into using search templates and making them be your way to show relevant content.
Hope that helps!

Related

best way to filter and search with vue3&django_rest

I'm new to vue and Django ,I want to implement a search component for a e-commerce project and filter the results as user want. i spent some time to find a proper way and here is what i understand so far:
front solution: for vue3 i can use vuex store and computed properties to implement search and filter the search results for example (https://softauthor.com/vuejs-composition-api-search-bar-using-computed-properties/#disqus_thread) the question is: 1) is it a good solution still when scaling, to store all products in vuex and filter and search them when search results are containing for example more than 500 or more products...
backend solution: with Django rest_framework: one way is to send the search result from Django and send a request for every filter and search option that maybe valid for getting highest discount in all products but not all cases i think...the question i have here is : 2) is it better to do the search through django and limit the number of result sending back instead of vue solution...
finally, should i mix the ways and use searching in all products through Django and some other conditions with vue
I saw lots of questions for search and filtering but didn't find one to explain my questions and i know i didn't narrow it down and i don't really know if I'm looking at it in the right way or not so please bare with me, if anyone can help me with an answer or some references to follow would be appreciated..thx
From my point of view is always better to do filtering backend. On backend you can control everything. Doing filtering on frontend on maybe 100000 items is going to be slower than letting django handle that.
Take a look at django-filter which is a good filtering package that goes well with django-rest-framework.

Add a skip parameter to Django CursorPagination

I'm looking to implement in Django 3(.1.7) something equivalent to the MongoDB cursor.skip() method.
What I'm after is an additional query parameter to provide to my cursor-paginated REST endpoints in order to skip a given amount of items from the result of the query.
I can't seem to find any example to obtain this result and I'd like not to reimplement the whole pagination class just to add this small addition.
What's the right way to implement this?
You can simply use slicing on your queryset page = My model objects.filter(cursorfield__gte=offset)[:page_size].
Have a look at the implementation of some pagination classes : https://github.com/encode/django-rest-framework/blob/98e56e0327596db352b35fa3b3dc8355dc9bd030/rest_framework/pagination.py#L395

Django change ordering of items in a Postgres ArrayField

dm_scripts = ArrayField(models.TextField(blank=True, null=True), default=list)
I have a Django model, and I wanted to use the ArrayField to store a list of TextFiles. The order matters, and I've been asked to allow a user to reorder these. How would you do that?
I've googled and searched here, but found nothing. Even Django's official documentation doesn't mention this.
I know this question is old, but I was looking for an answer, found one and thought I'd post the solution in case it is useful to others
A Django Postgres ArrayField is basically a list (at least in your case), so once you access it like object.dm_scripts you can manipulate it like any other list. For example, if you need to sort something alphabetically, you can call:
ordered_array = sorted(object.dm_scripts)
ordered_array.save()
Afterwards the list items will stay in that order. You can call that and apply it anywhere necessary, in a view, a def save method or whatever.
After that it's up to your imagination. Implementation would really depend on the UX interaction. I think it would be easy to pass the list to a javascript front-end, have the user reorder them visually, then apply the new order to the list items (Or many surely more optimised methods).

Query on a Many to Many relationship using through in Django

I'm new in Django and I'm giving myself a big headhache trying to structure this query.
I have a BaseProfile connected with a OneToOne field to User.
I'm specializing the profile in CustomerProfile connected with a OneToOne field to BaseProfile.
A CustomerProfile has a ManyToMany relationship with other CustomerProfile (so itself) through a RelatedCustomer model.
In the RelatedCustomer I specify the from_customer and to_customer Foreign Keys.
Maybe with an image you can understand better.
My problem:
Given a user.id I need to know all the other user.id of the customers that he is connected to (so passing through from_customer and to_customer):
So basically, first I need to dig from User to RelatedCustomer using reverse lookup, take all the set, and then going back to know the user.id of each customer in the set.
EDIT2:
What I've reached so far:
# This gives me back a customer profile given a user.id (2)
cm = CustomerProfile.objects.get(base_profile__user=2)
# M2M lookup. Given one customer returns all the RelatedCustomer relations
# that he has as a part of the 'from' M2M
cm.from_photographer.all()
Chaining the previous two: given a user.id I obtain a queryset of CustomerRelated relations:
rel = CustomerProfile.objects.get(base_profile__user=2).from_photographer.all()
This gives me back something like:
[<CustomerRelated: from TestCustomer4 to TestCustomer2 >,
<CustomerRelated: from TestCustomer4 to TestCustomer3 >]
Where in this case the user having a user.id=2 is the TestCustomer4.
My question:
So far so good, but now having this set how can I get all the user.id of the to_customer?
That is, how do I get the user.id of TestCustomer2 and TestCustomer3?
Firstly, this is not how you query the database in django. Secondly (since you're learning), it would be good to point out that you can run dbshell to try out different things. And lastly, this kind of problem is described in the documentation.
I am telling you this, because as a beginner, I also felt that it was a little difficult to navigate through the whole thing. The best way to find things is just to use google, and add a django at the end.
I know how you feel, the documentation search sucks, right? Heh, I feel you, that is why you always search the way I described it. Once you get a hang of the documentation, you will feel that the documentation title page is a little more intuitive.
Okay, so now to the answer:
To access a ManyToMany, OneToOne or ForeignKey field, you need to use a __ commonly known as dunder.
So, this is how I would go about doing this. Please note that there are other ways, and potentially better ways of doing this:
thing_I_want = RelatedCustomer.objects.get(to_customer__id=2)
Note, however that if you wanted to get a list of customers you would use filter(). Here is an example (which uses number of purchases as an example):
things_I_want = RelatedCustomer.objects.filter(to_customer__no_of_purchases=16)
Also note that the great thing about filter is that you stack one filter on top of another. You can read more about these features in the documentation link I provide below.
That will get you what you want. Now, you might have more queries regarding this, and how it all works together. Not to fear, please click this documentation link to check it out.
EDIT
Seems like what you want to do can be done by django, but if you want to do it using sql, then that is possible too. For example, SomeModel.objects.raw("SQL_HERE"). The name of the tables are usually <app>_<model>.
However, what you are asking can also be done in django, using the ORM. But it will be tricky.
Ok, as usual whenever you get the answer it always look much more easier than what you were expecting.
I guess this worked for me:
User.objects.filter(base_profile__customer_profile__to_customer__in=
User.objects.get(id=2).base_profile.customer_profile.from_customer.all())
Many thanks to #Games Brainiac

Django passing querysets between pages

I have a view which does a pretty heavy query on three separate databases and outputs the count of each query into a template. From the the user can go to one of the three results and get the detailed results. I don't want to repeat myself in my views and I want to maximize performance, so my question is what is the best way to achieve this result?
Can I pass a queryset to another page (get or post)?
Should I save the queryset in a session (I am not currently using session for this project as it is fully public)
Or is there a better way?
I know this is not a highly specific question, but I would appreciate any advice on this (I'm guessing - not uncommon) situation.
From my experience, I think saving your result on session is a good and simple solution.
Save the result of the querysets to the session. When I say to save the results, what I mean is to run list() on it to execute them, and then store the resulting list in request.session.
sounds like you want to have a look at caching