Role of django filters. Filtering or upfront formatting within the view? - django

I would like to hear your opinion about this.
I have a django application, where the data obtained from the model are rough. To make them nicer I have to do some potentially complex, but not much, operation.
An example, suppose you have a model where the US state is encoded as two letter codes. In the html rendering, you want to present the user the full state name. I have a correspondence two-letters -> full name in another db table. Let's assume I don't want to perform joins.
I have two choices
have the view code extract the two-letter information from the model, then perform a query against the second table, obtain the full name, and put it in the context. The template renders the full state name.
create a custom filter which accepts two-letter codes, hits the db, and returns the full-length name. Have the view pass the two-letter information into the context, and put in the template the piping into the filter. The filter renders the two-letter code as a full string.
Now, these solutions seem equivalent, but they could not be, also from the design point of view. I'm kind of skeptical where to draw the line between the filter responsibility and the view responsibility. Solution 1 is doing the task of the filter in solution 2, it's just integrated within the view itself. Of course, if I have to call the filter multiple times within the same page, solution 1 is probably faster (unless the filter output is memoized).
What's your opinion in terms of design, proper coding and performance?

It seems to me your model should have a method to do the conversion. It seems like extra work to make a filter, and I don't think most Django developers would expect that sort of thing in a filter.
A filter is meant to be more generic - formatting and displaying data rather than lookups.

My oppinion is that the first solution is much cleaner from a design point of view. I'd like to see the template layer as just the final stage of presentation, where all the information is passed (in its final form) by the view.
It's better to have all the "computation logic" in the view. That, way:
It's much easier to read and comprehend (especially for a third party).
I you need to change something, you can focus on a particular view method and be sure that everything you need to change is in there (no need to switch back and forth from view to template).
As for performance, I think your point is right. If you want to do the same lookup multiple times, the 2nd solution is worse.
Edit:
Referring to ashchristopher's comment, I was actually trying to say that it definitely does not belong to the template. It's never really clear what business logic is and where the line between "data provision" and "business logic" lies. In this case it seems that maybe ashchristopher is right. Transformation of state codes to full state names is probably a more database related encoding matter, than a business logic one.

Related

Couchdb "Get By Type" view design

So for my documents, i have a type property that defined them. And almost for all of these 'types', I have to have a 'get by type' call..
Now the question is which one of these design is more efficient;
Have a single view that has a key with the 'type' that maps all of the documents
Have a view for each 'type' that just maps those types, and I can query the view to get all the documents in the view?
It depends from how many "types" you have in your db. If few - go with "view per type" approach and you'll be fine and have nicer API URLs.
However, when you'll have around 70 types (my case) of documents within single database it would be too oblivious to understand that this approach isn't work anymore and you need one single view to filter docs by type - you'll never forget to add your special view for new doc type, you don't need to cleanup outdated views. As bonus feature, having single view allows you to retrieve docs of multiple types with single request and have only one replication task that syncs multiple types of docs between databases. Same is true for every other fields that are common for a every or most part of docs (like author, updated_at etc.).
Final decision is yours, but better to take the way that will free you from additional work and one additional query parameter is not much higher cost to have relax.
I think the latter is best. Have a view for each type that queries/filters for that particular type. This allows you, from the Futon views drop down, to very quickly display lists of docs of the particular type(s). Almost like you're looking at "tables". But not really ;-)

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! :)

Application logic in view code

Should I be writing application logic in my view code? For example, on submission of a form element, I need to create a user and send him an activation email. Is this something to do from a view function, or should I create a separate function to make it easier to test down the road? What does Django recommend here?
I found it very hard to figure out where everything goes when I started using django. It really depends on the type of logic you are writing.
First start with the models: model-methods and managers are a good place to perform row-level logic and table level logic i.e. a model manager would be a good place to write code to get a list of categories that are associated with all blogposts. A model method is a good place to count the characters in a particular blogpost.
View level logic should deal with bringing it all together - taking the request, performing the necessary steps to get to the result you need (maybe using the model managers) and then getting it ready for the template.
If there is code that doesn't fit in else where, but has a logical structure you can simply write a module to perform that. Similarly if there are scraps of code that you don't think belong, keep a utils.py to hold them.
You shouldn't perform any logic really in your templates - instead use template tags if you have to. These are good for using reusable pieces of code that you you neither want in every request cycle nor one single request cycle - you might want them in a subset (i.e. displaying a list of categories while in the blog section of your website)
If you do want some logic to be performed in every request cycle, use either context processors or middleware. If you want some logic to be performed only in one single request cycle, the view is probably the place.
TLDR: Writing logic in your view is fine, but there are plenty of places that might be more appropriate
Separating the registration code into it's own function to make testing easier is a good reason. If you allowed admins to register users in a separate, private view, then a registration function would be more DRY. Personally, I don't think a little application logic in the code will do to much harm.
You might find it instructive to have a look at the registration view in the django-registration app -- just to see how it's written, I'm not saying you should or have to use it. It has encapsulated the user registration into it's own function (there's a level of indirection as well, because the registration backends are pluggable).

django: generic views + custom template tags or custom views + generic/normal template tags

This is more of a best-practices question, and given that I'm quite tired it mightn't make much sense.
I've been putting together a blog app as a learning experience and as an actual part of a website I am developing.
I've designed it like most apps so that you can list blog posts by multiple criteria i.e.
/blog/categories/
/blog/authors/
/blog/tags/
/blog/popular/
etc.
On each page above I also want to list how many entries are a part of that criteria
i.e. for "categories", I want /blog/categories/ to list all the different categories, but also mention how many blog posts are in that category, and possibly list those entries.
Django seems to give you lots of ways of doing this, but not much indication on what's best in terms of flexibility, reusability and security.
I've noticed that you can either
A: Use generic/very light views, pass a queryset to the template, and gather any remaining necessary information using custom template tags.
i.e. pass the queryset containing the categories, and for each category use a template tag to fetch the entries for that category
or B: Use custom/heavy views, pass one or more querysets + extra necessary information through the view, and use less template tags to fetch information.
i.e. pass a list of dictionaries that contains the categories + their entries.
The way I see it is that the view is there to take in HTTP requests, gather the required information (specific to what's been requested) and pass the HTTP request and Context to be rendered. Template tags should be used to fetch superflous information that isn't particularly related to the current template, (i.e. get the latest entries in a blog, or the most popular entries, but they can really do whatever you like.)
This lack of definition (or ignorance on my part) is starting to get to me, and I'd like to be consistent in my design and implementation, so any input is welcome!
I'd say that your understanding is quite right. The main method of gathering information and rendering it via a template is always the view. Template tags are there for any extra information and processing you might need to do, perhaps across multiple views, that is not directly related to the view you're rendering.
You shouldn't worry about making your views generic. That's what the built-in generic views are for, after all. Once you need to start stepping outside what they provide, then you should definitely make them specific to your use cases. You might of course find some common functionality that is used in multiple views, in which case you can factor that out into a separate function or even a context processor, but on the whole a view is a standalone bit of code for a particular specific use.

Controller logic and template logic, where do you draw the line with pagination?

The whole point of an MVC framework is to separate design (templates) from logic (controllers). However, template languages often afford a limited degree of "design logic" to occur. This includes basic if statements, loops, filtering, etc.
I've created a Django template tag that can take any list or QuerySet and "pagify" it. It splits the list up into pages based on a specified page size then adds the pages into the Context. The usage is as follows:
{% pagify articles by 20 as pages %}
I can then call a separate include to iterate over the pages and produce a nice list of pages wherever I needed it.
This seemed like an optimal way to do it because it allowed me to page any list in the context; I didn't have to rely on the controller to return paged results. But a colleague argued that this seemed like too much logic for the template. I thought this still fell within the realm of design-based logic since the page would still function even without paging, and determining page size feels like a template responsibility.
My question, is this too much logic for the template? or is this a clean way to be handling this?
It's always been my understanding that the view isn't supposed to be devoid of logic. It's just supposed to be devoid of any controller logic. Paging just has to do with how the data is displayed which is exactly what the view logic is supposed to contain.
Put it this way; what if you were using your data model in another medium, say, not on the web but via some kind of console-based application or background task? Wouldn't it be nice to be able to get "pages" of data through a controller (or manager) rather than having to somehow rely on a template to do this work for you?
While I'd certainly agree that the "look" of the paged data should be handled by your template, the "act" of paging should be left up to a controller (Django view) or even through some kind of custom manager (models.Manager) method.
The view should not contain business logic or navigation logic. What you are describing is presentation functionality (carefully avoiding the l-word here), which can be placed in the view layer.
You may want to check out django-pagination, which provides a similar template tag.
I agree with your colleague; the template should be fed paginated data rather than performing the pagination. The key question, I think, is whether determining page size is a template duty, and I don't think so; I'd say it should be handled at a higher level.