Add a skip parameter to Django CursorPagination - django

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

Related

Getting the count of a Filtered Result in a template on Django

Im trying to access a related model on the template like this:
course.course_set.all.0.section_set.all.0.student_assignation.count
The problem is that I would like to count all the student assignations which have an active = True property.
I would like to be able to do something like this:
course.course_set.all.0.section_set.all.0.student_assignation(active=True).count
How can I accomplish this on the django template?
Django templates are note meant for such complex queries.
There are a few ways you can handle this
One, create a custom django template tag
Two, create a class method which would provide this info.
Example
class Course:
...
def sutdent_assign_count(self):
#Your query goes here..
You have far too much logic in the template. Create a method on one of your model classes that actually returns the number you want; I'd propose one, but it's too unclear what you're doing (why the .all.0, aren't the other results important? Why course.course_set, is that a many to many to itself?). What are your models like?
How would you describe what you are displaying in English? That probably gives a hint to what kind of method you should create.

django design pattern/best practice: filtering a queryset

I have a page where I'm displaying the results of a queryset to the user.
What i'd like to do is allow the user to click on a link in order to apply a filter.
Currently what I do is have the links pass "get" parameters to the page in order to apply filters. The filters can be references to other models or custom filters (e.g. an unassigned filter)
In order to provide a decent user experience the implementation needs to do a few things
in the view:
check that the filter parameter passed is valid
check what type of filter it is (based on other models or a custom filter) in order to apply the correct condition to the queryset
(optional) a way to make the filters cumulative (i.e. you can keep adding filters)
in the Template:
display the correct resultset based on the filter choosen
when displaying the filters, recognize which filter we have applied so that the current applied filter is displayed as text not a hyperlink.
I'm thinking this must be common enough that someone must have like a design pattern or best practice figured out for this other than the obvious whack of if/else statements in the view and the template.
is there?
I find the way the Django admin handles this kind of functionality a great pattern. If you're not familiar, check out the list_filter option in the admin. It's similar to what you're describing, but yours is a bit more generic. Perhaps this will help you ponder some ideas?
First, for the actual querystring chunk, you're simply passing the Django-ORM lookup key and value pair. e.g., ?sites__id__exact=1, tags__in=words, etc. Since you want to allow for cross-model lookups, you'd need to provide another parts in the string to include the model name, not too tough.
For checking if the filter is valid, you can simply ensure that the model/field lookup is valid. By splitting the parts of each QS chunk, you can identify the model, the fieldname, the lookup, and the value. Then, use Django's built-in functionality to validate that fieldname exists on model. You can do this with ForeignKey's too. Here's how Django does it
You can keep adding filters pretty easily to this. You'll be providing your view and the form that's displaying these filters with some context, so it'll persist and re-populate for the user. Also, you could just as easily persist the query string. Basically, you'd have the same read / parsing functionality here at all times, nothing really different.
I think the keys are automating and keeping it as DRY as possible. Don't succumb to a bunch of if statements. It's really easy to pass these lookups into the ORM, safely too, and it's really easy to catch bad lookups and provide the user with a meaningful error message.
I hope that helps you on your path! :)

Order object_list with django-profiles

Using the django-profiles app, I want to display the users' profiles in an ordered list.
Ordered by different fields, depending on the situation.
Now the docs say something about passing extra arguments to the views here but I don't know how to do that, since the urls are just included (as opposed by defined by myself).
So,how can I pass in the "order_by" part that I can just use in the normal list view?
Checking the code [1], there is no way to alter the queryset in the way you want.
Your best option is probably to write this view yourself, using the existing implementation as a guide if you like (e.g. you can still call object_list when you've got a queryset ordered to your specification). Then either override the profile list URL in your own urls.py by declaring it first:
...
url(r'^profiles/$', path.to.my_profile_list_view, name='my_profile_list'),
(r'^profiles/', include('profiles.urls')),
...
or create a new URL for this and use that on your site instead:
url(r'^ordered-profiles/$', path.to.my_profile_list_view, name='my_profile_list'),
[1] https://bitbucket.org/ubernostrum/django-profiles/src/c21962558420/profiles/views.py#cl-287
See also: https://bitbucket.org/ubernostrum/django-profiles/src/c21962558420/profiles/urls.py

In Django, should a function to reshuffle objects for a specifc view go into the model or the view?

I'm asking for general guidance on what functionality should go into the view code versus the model code.
Specifically, I have a function that takes a list of objects and shuffles them into a list of lists based on whether or not a field has changed. For example:
[{a:1,...},{a:1,...},{a:2,...},{a:1,...},{a:1,...}]
will be transformed into
[[{a:1,...},{a:1,...}],[{a:2,...}],[{a:1,...},{a:1,...}]]
The purpose of this transformation is to prep the data for rendering in a template as nested loops.
Should I create a model function like group_objects(queryset) or should I put this logic into the view? More importantly, what's the thinking behind your recommendation?
If this function is for template rendering it should be a custom template tag (or filter).
And look at regroup filter, may be it can be used for your task.
The Django docs specifically state that table level functionality should preferably be implemented in a model manager (link). So I guess that if you want to follow the Django standards you'd implement it in the model manager.

Django + Haystack how to do this search

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!