django render understanding context_instance - django

I am reading:
https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#render
If I understand correctly context_instance is automatically created from the first parameter (request).
How are these values presented to the view? Does it combine them with the dictionary parameters?
What types of things are normally in the context_instance? (I know it is built from request).
I have also read that template pre processors can add data to context_instance.
I am just trying to understand how I can use context_instance and have been searching and haven't quite found the right answer

Template context processors are the only things that affect the context in any way from a render call. All of these - either the default ones, which add things like user, or your own custom ones - simply add elements to the context dictionary.

Related

Should I pass a dictionary to my template?

Being a newb I'm trying to work out what belongs where. I've got a ListView to list all users in the system, and it includes a get_queryset method -something along the lines of:
def get_queryset(self):
users = []
for user in User.objects.all():
a_user = {}
a_user['username'] = user.username
a_user['full_name'] = user.get_full_name()
a_user['num_of_friends'] = len(user.friends.all())
a_user['phone_num'] = user.get_profile().phone_num
a_user['has_subscription'] = bool(Subscription.objects.filter(subscriber=self.request.user))
users.append(a_user)
return users
So rather than returning a queryset of users I'm making this dictionary out of various chosen attributes of each user, and what a template designer gets is limited to only what I think they should have.
Is it better practice to instead pass user objects to the template, and let the template writer get whatever they need from them? I suppose the answer is Yes.
But, when it comes to the a_user['has_subscription'] line above, I assume the answer becomes No?
The way you've done it is totally fine. I've found it to be useful to separate my templates from my model by explicitly providing the information needed by the template in the view, which is essentially what you've done. It's a little bit weird to not be returning an actual queryset from a method called get_queryset, but I've also come to the conclusion based on criticisms like this that class-based views as they are currently implemented in Django should be considered a means to an end, as opposed to a dogmatic way of organizing your view code. The abstraction simply isn't as clean as say, the Django ORM.
If you really wanted something a little slicker, you could try using the values method to narrow your queryset, with an annotation to add in the subscription count. But there's probably not much point.
It depends on what you're trying to do with the array 'users'. Someone editing the template can only style and display the data in a certain way. The get_queryset function can provide the data for the template.

Differentiate Context, Request Context in django

What is the difference between Context, Request Context in django?
Why do we need context processors?
RequestContext simply goes through your TEMPLATE_CONTEXT_PROCESSORS setting and adds variables in addition to the ones you explicitly pass to the context class.
The context processors are literally just a function that accepts request as the first argument and returns a dictionary to be added into the context.
Why do you need them? Because some very common operations like adding the currently logged in user or STATIC_URL variables to the context would get highly repetitive if not automated.

Handling url reverse function for django view with multiple kwargs

I'm building a database application using django. Much of the data recorded requires supporting documentation (this documentation is scanned in and uploaded). Many of my django views include links to my scanning view, and arguments are passed into that view. In fact the view that handles the scanning takes 9 optional kwargs. I can't work out how to set up my urls.py so as to handle the following:
HttpResponseRedirect(reverse('general_doc_upload', kwargs = doc_parameters))
I'm sure there must be a nicer way of handling this than trying to write Regex for every possible combination of kwargs.
Unfortunately the I don't have a lot of leeway with the underlying database structure, this has been specified by the client, the django models (and corresponding views) have been written to fit this structure.
This sort of thing is where putting the parameters in the URL breaks down. Instead, you should pass them as GET parameters - /my/url/upload/?param1=foo&param2=bar etc.
In your urlconf, just match the basic pattern with r'upload/$', and get the parameters in your view with request.GET['param1'] etc.

Can custom Django filters access request.user?

Is it possible to access the current User (i.e. user in the template context) from a custom template filter?
Obviously I can pass the user in as an argument, but if it's possible to just grab the current user, that would be more convenient.
Django filters aren't given any special access to the context from which they are called, they're just plain old functions.
You'll need to pass in anything you want to use within the function.
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
See my answer here:
https://stackoverflow.com/a/28098279/201945
But, in short, you CAN access the context from within a custom filter by extracting it from the call stack when, and only when, the filter is called during render.
This is, admittedly, a haphazard solution. Caveat emptor.

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.