I think that is the right way to ask it. I'm wondering which parts of the code execute first, second, etc.
My assumption would be, but I don't know:
Request
Middleware
View
Model
Middleware
Response
The reason I'm asking is because I want something to happen dynamicall in the Model based on a request variable and I'm trying to device the best way to automatically add the request in to the model layer without passing in via the views. I would assume that some sort of middleware fantastic contraption would be the way to do it somehow.
To answer your clarification comment -- You can't get there from here.
models.py is just a file where you put model classes, which are just classes that get accessed from all over the place. Unless the request object is passed to the function you're working with, then it does not exist, and there is no request.user. Models can be used from anywhere, not just from within contexts where there's a request.
If you need to work with the request object, then pass it as a parameter. And if that doesn't make sense, then you're using your model wrong.
Neither the model nor the templates are ever part of the stack. Do your work in a view.
I think it's more like:
Request
Middleware (URL mapper)
View
Model (if requested by the view)
Template (if requested by the view)
Middleware (response output)
Related
I am learning Django out of pure passion and I seem to have trouble understanding some core principles of Django that really give me headackes and i tried searching online and reading the docs but i don't seem to fully understand. I'll just simply shoot the questions and try to be clear . I apologise for anything stupid I say . I am just trying to get my knowledge straight.
1. What is a "request"?
OK, so I am thinking of a GET request for a webpage but online i see python code like self.request.user.is_superuser and i am thinking of an User object fetched and displayed to the template to which i can apply User methods. It is clearly more to this request than i already know.
2. CBV's built in methods. The get methods. How do they execute? In what order.
I noticed programmers override these methods sometime . If i redefine more than one method in a CBV i start getting weird behaviour.
For example if i declare and redefine 2 methods in a Detail View get_object() and get_queryset() which of them will be executed first after calling the view? Being a method it should be called somehow in order to execute but i don't know the order how these methods are called for a CBV if there is more than one. Probably i should only define one of them, not both.
3. Queryset. Is it a list?
I have an ideea what querysets are and that you can apply filters to them but what do they return? Do they return objects of the model i am querying?.
OK so, if i have a DetailView CBV and override the get_queryset() method will this return on object and pass it to my template?. Here I am using a filter but what if am not using a filter. What will the CBV return? Will it return the entire set of objects?
class UserDetailView(LoginRequiredMixin,DetailView):
context_object_name='user_detail'
model=models.User
template_name='basicapp/user_detail.html'
def get_queryset(self, *args, **kwargs):
qs = super().get_queryset(*args, **kwargs)
if not self.request.user.is_superuser:
qs = qs.filter(pk=self.request.user.pk)
return qs
4. Can you kindly recommend a Udemy course, video course or book where querysets, CBV methods and ORM are explained clearly?
Preferably video cause it makes so much difference when i see the code working
The thing is I understood how the MVT mechanism works but these class built in methods and overriding them gives me a lot of problems . I never encountered them before and when i start using them I feel like as if i am walking in the dark .
Sorry for the long post.
Thanks
What is a request?
It is a HttpRequest object [Django-doc]. This is an object that contains data about the request the client made to the server. For example this contains an attribute .method [Django-doc] that contains a string like 'GET', 'POST', 'PATCH', etc. that specifies the request method used.
but online i see python code like self.request.user.is_superuser and I am thinking of an User object fetched and displayed to the template to which I can apply User methods.
One can install middleware [Django-doc], this is tooling that pre-processes the request, or post-processes the response. Normally the AuthenticationMiddleware [Django-doc] is added in the settings.py file by default. This will add an extra attribute .user to the request that lazily loads the user that has been logged in. If you would remove this middleware, the .user attribute will no longer exist.
CBV's built in methods. The get methods. How do they execute? In what order.
That depends on the specific class-based view. The documentation however specifies how most methods are performed. For example for a ListView [Django-doc], the documentation mentions the method flowchart:
Method Flowchart
setup()
dispatch()
http_method_not_allowed()
get_template_names()
get_queryset()
get_context_object_name()
get_context_data()
get()
render_to_response()
It also links to the methods that explain what these are doing.
In essence, each class-based view can have methods like get, post, put, patch, etc. Based on the method of the request, the request is dispatched to the method with the same name.
Queryset. Is it a list?
No. A QuerySet is an object that more or less represents a query that you can perform on the database. QuerySets are lazy. That means that as long as you do not iterate over them or for example call len(…) over these, they will not make that query. If you iterate, etc. over these, they will make a query to the database, and then you iterate over the result of the query. The results are normally wrapped in model objects (unless you use functions like values(…) [Django-doc] or values_list(…) [Django-doc].
Can you kindly recommend a Udemy course, video course or book where querysets, CBV methods and ORM are explained clearly?
It might help to start with the Django tutorials. These go step-by-step over the architecture of Django. The documentation on the QuerySet API explains how you can make querysets. The page on Query expressions gives examples on how to make more advanced queries. Finally the Django documentation also has a page on class-based views.
Hey im kinda new to Django and the whole Views/Request process.
So I noticed i got the auth_user inside the request object due to the User middleware I had inside the settings file, and anywhere i have the request, i can call the user object with request.user
I kinda have a similar modal/object that is pretty important and I saw how to create a basic middleware but I'm not for sure how to replicate similar functionality where I'd be able to access that specific object inside the request like "request.object"
Edit: Okay i figured it out, but now the question is how do i reinitialize the process request in a view based on different conditions.
For example:
It starts off as a default of
def process_request(self,request):
request.object = Object.objects.get(id=1)
But based on a specific thing that happens in the views, i want it to change to a different id?
I'm converting some django views to be class based, and so far loving the flexibility.
Most of my views subclass from a parent view ClubView. Each subclassed view that needs to handle a post() method override needs to have access to the corresponding club value.
This value is in the URL, so the request variable has it. However, is there a way for me to grab this value, and fetch the corresponding club object outside of the post() method? like a pre-post() method or something. Mainly because I don't want to copy/paste club = Club.objects.get(...
A more general question -- in what order do all the methods execute in? Django's documentation on this seems lacking.
This DjangoProject page on Generic Display Views seems to be the most helpful, imo.
It covers both ListView and DetailView and explains in detail the methods executed in a class-based display view -- Here's an example of DetailView methods called:
setup()
dispatch()
http_method_not_allowed()
get_template_names()
get_slug_field()
get_queryset()
get_object()
get_context_object_name()
get_context_data()
get()
render_to_response()
Actually, you're really doing it upside down. Instead of a central ClubView, it's more flexible to have one view class for each of the individual actions/pages. E.g., you might have something like this:
class ClubListView(ListView):
model = Club
class ClubDetailView(DetailView)
model = Club
# etc...
This way you only need to override specific functionality unique to each of those actions, by defining a particular method on the view class which does what you need. E.g. you need to filter the possible Clubs in the ClubListView dynamically, based on something from the request? Just override the ClubListView.get_queryset method to apply the appropriate filter.
If there is some really peculiar behaviour that needs to be applied to all the views, it depends on what this behaviour really is about: if it's related to this specific model, it should probably best be defined in the model itself, or perhaps its manager; and if it's really something specific to the views, you should write and extend a mixin along with the actual view class.
dispatch is called before post - or, for that matter, get depending on the request. Overriding it should let you set extra information.
The docs lack detail - I didn't really get it until I read the source. But the source is nicely readable except for being spread across multiple files.
You could write a get_club method in your parent class. You can then use this in your subclasses, and you don't have to repeat the logic.
I am working on an app which would enable a preview function for a model. Models marked as preview-able would allow for changes to be made in the Django admin interface and previewed on site using the same view as would an object of that type normally use to render itself, but rendered instead with the new (unsaved) object in it's place.
This is a pretty easy task to do in a bespoke fashion when you know the views or templates ahead of time. But I want this to be reusable and simple.
What I Was Thinking
My idea would be to apply the resolve() urls function to the existing (saved) object's get_absolute_url() value to discover the view used dynamically. Then call that view, get the returned HTTPResponse and alter it in some fashion before returning it myself.
The Problem
It seems that by the time the HTTPResponse is returned by the object's natural view the HTML has already been rendered by the template engine.
So I guess the question is: Is there a way to get at a HTTPResponse before the template is rendered and alter the context variables before that happens.
If not then could the same idea be implemented in another fashion. Would using middleware change anything (your still working with a HTTPResponse object there as well).
Thanks,
Marcus
P.S. If you come up with a radically different methodology to solve this problem, I will be sure to attribute that concept to you in the app documentation (despite it being a small app right now).
It is not trivially possible no, the easiest way would actually be to write your own template context processor that checks for example if something like GET['preview'] is set, then sets dictionary values based on some other GET or POST data. Furthermore when other variables are added it should make sure these don't overwrite the existing values set by this method (otherwise the view would override it anyway with some other data).
One remark however: completely unintrusive behaviour will often lead to erroneous behaviour. If the view does not know of this preview functionality and e.g. it expects a valid id or redirects to an error page, your preview won't work (as you don't really have a valid id). Choosing for views that know of this preview functionality is indeed some more work but will certainly be correct. You could try to make it more generic by using decorators or callable view classes (which can be derivable from some generic base) instead of view methods.
A completely different approach that is only slightly 'view' intrusive, I assume you do not want to save the model so it doesn't show up in public listings. An approach could be to add a 'preview' field and use managers to restrict lookups, so something like this:
class NoPreviewManager(models.Manager):
def get_query_set(self):
return super(MyModelManager, self).get_query_set().filter(preview=False)
class MyModel(models.Model):
... #other fields
preview = models.BooleanField()
objects = NoPreviewManager()
allobjects = models.Manager()
In all normal views you can just use MyModel.objects so previews won't be listed. In the object-specific view you use MyModel.allobjects to also enable defailed views of previews. This way you don't have to do weird view hijacking things, but you should take care preview objects get cleaned up if they aren't promoted to real objects. Note that you can also combine many of this logic into a base class.
I'm serializing User objects to JSON, and I'd like to indicate in the JSON response whether the serialized user is friends with the user making the request.
I've added a to_dict() method to my User model that does the pre-processing necessary to serialize the object--that would be a nice place to add an attribute indicating friendship, but since User.to_dict() doesn't have access to the request object, I can't seem to do it there.
Doing it in a view is easy, but I don't want to repeat that code in other views. I'd like to "upgrade" User objects to request-aware User objects.
The django.contrib.auth User model has an is_authenticated attribute, which is really an attribute of the request and not of the model--that attribute only makes sense within the context of a particular web request.
It's as if I should replace request.user with an instance of RequestUser, a new class that takes a User and a Request and adds request-specific attributes. What's a clean way to do that?
This doesn't really answer your question, but are you sure you want to handle friendship through a method on User? I say this because:
The logic surrounding friendship is presumably in another app, so you might want to be explicit about calling a function defined in that app;
Friendship is almost always a symmetric relation, so using a method on User leads to redundancy (a.is_friend_with(b) == b.is_friends_with(a)). If you later want to cache the result of the call, for instance, it makes sense to define a function which simply accepts user objects as arbitrarily ordered arguments; and,
You probably don't want to do anything too fancy with HttpRequest or User as it's likely to confuse other developers.
My approach would be to define a manager method on whatever model represents friendship, and explicitly pass in users to that, like so: Friendship.objects.are_friends(other_user, request.user).
You could create a proxy model of auth.User and add your is_friend method there. http://docs.djangoproject.com/en/dev/topics/db/models/#proxy-model-managers
As for the is_authenticated method, its a little simpler than you may think. The user context processor makes a special type of user available if they are not logged in, that is the AnonymousUser. This class always returns False when is_authenticated is called. Likewise the regular User class always returns True when is_authenticated is called.
In short, don't worry about the request object. If the current user is not logged in, the user variable available in your view will be using the AnonymousUser class and your is_friends method will not be found.