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?
Related
Firstly, sorry if the question is so obviously (I'm quite newbie). I have a Django project where the user can add or remove, for example, interests to his/her profile (ManyToMany relationship). I've achieve this with 3 views. The first one where the profile's interests are rendered, the second one to add (nothing is rendered, when the user click a link, the view just update the profile and return the first view, the one with the profile's interests) and the third one to remove interest.
urls.py
path('home/overview/add/<int:interest_pk>', add_view, name="add_view"),
views.py
def add_view(request,interest_pk): #the third (the one to remove) view is similar
user = request.user
user.profile.interests.add(Category.objects.filter(pk= category_pk).get())
return redirect('overview') #Overview is the view where the interests are rendered
This works but now I'd like to improve this making it asynchronously. So here is my question, should I use Django Rest Framework to handle this kind of request (the ones related to the POST and DELETE methods) or is there any other method?
Note: I'm not using forms to send the information (I'd rather not to use it because it's simpler to send in an url the pk of the interest and handle it in a view) and I think it could be achieved using only requests. (Correct me if I'm wrong)
I'm new to django, so I apologize if this has been asked. I'm using the post_save signal to run a task when a new object is created. I need to be able to check if the form was submitted from the admin page or if it was submitted on the live website, is this possible? Where might I find documentation on this?
post_save is too late in the process to log or take action on the source of the object.
post_save is a signal sent from the database/ORM, i.e. it is what is called after a save is done. Does the save function take any input about the source? No. Does that function put anything into the ORM or the database about the source? No.
You want to take whatever action it is in the view function where this occurs. Here is the simplest way to do it that I can think of. I shall assume that your preferred choice of action is to save where it was created in the database.
Consider the following:
class YourObject(models.Model):
name = models.CharField(max_length=30)
creation_location = models.CharField(max_length=30, default="Admin")
Here we have an object with a name and a creation_location, the purpose of the second being to tell where the object is created. To prevent any need to edit the Admin functionality, as that can be a pain, the default value is set to Admin.
Onto the view:
def create_model_view(request):
your_object = YourObject.objects.create(name='FirstObject', creation_location="View")
Here we have a view with a create function for the object. In the initialization, the default value of Admin for the creation_location is overwritten and set to View.
I have a view that handles a POST request and attempts to create a new object. However, I know that some of the POST'd data is invalid... But I want to fix it and go ahead and create the object.
The only way I can figure out to be able to 'fix' data in a ModelForm is to create a 'is_valid()' form. To do this, I can either create the form with the POST data, or I can create it with an already existing instance. Unfortunately, if I use the POST data, because some of it is invalid, the form won't validate and I am thus unable to get to the data in the form to fix it. If I create it with an already existing instance, this works, but when the form is displayed, any remaining errors are for whatever reason ignored (and thus don't show up on the web page.) I've tried a combination of creating the the Model form from the POST data and giving it an instance, but this doesn't seem to help. Additionally, I've tried modifying (a copy of) the POST data, fixing it, and then creating the ModelForm from the 'fixed' POST data. This sort of works, with the exception that I have some ImageFields in my form, and they seem to just be ignored.
Any help would be greatly appreciated. I have looked at every good page that I can find to no avail.
Perhaps there is a better way to do this? The problem I'm trying to solve is that I want to have a model that contains ImageFields. The first time I put up the form, the user needs to 'upload' images for each of the fields. However, if he doesn't update an image for one of the fields, I want the new form to come up with a Image upload button on the fields where images have not been uploaded, and just a text field with the image name for images that have been uploaded.
Edit 9/15/2010:
Ok, I think I can simplify all of the above question into this:
def testing( request ) :
test_form = UserProfileForm()
valid = test_form.is_valid()
return render( 'testing.tmpl', locals(), request )
When the above code is rendered, the 'valid' shows as False (as one might expect), but the 'test_form' renders without any errors. I've read through (if perhaps not understood?) the documentation on Models and ModelForms, and I see that most of the time a ModelForm (in my case: UserProfileForm) is created with a specified 'instance'. However, 1) I don't have an instance yet, 2) I would still expect the non-instance'd Form to display errors. I'm sure there is something I am missing. Please illuminate. :)
One more thing, which perhaps the answer to the above will answer anyway, but as far as I can tell, the is_valid() call is supposed to call the 'clean()' function I defined for the UserProfileForm. However, (not being a python guru) I placed 'raise ValidationError()' at the top of clean(), and when I run the code, no error is shown. Thoughts?
Update: I figured out the problem and the answer is below. Thanks!
You should have a look at how to clean form fields in django. You could either manipulate the data returned from the form there or make any kind of validation!
If your ImageFields are optional then you can still validate them (that they are otherwise correct).
Then it's a matter of adjusting your template to show either the uploaded file name or an file upload field depending on whether they've already uploaded one or not. Actually, it would probably be better to give them both fields in the first case. That's what the automatic admin does (the upload field is labeled "Change").
Well, after figuring out how to use the python debugger (pdb) and the fact that within emacs it kind of 'just works' (wow!?) I was able to find that my (empty) form was not bound. Googling bound forms pointed me to this page:
http://docs.djangoproject.com/en/dev/ref/forms/api/
RTFM'ing I find that I can pass an empty dictionary to my form and then everything starts to behave as I would expect. So, to summarize, there is a big difference between:
test_form = UserProfileForm()
and
test_form = UserProfileForm( {} )
The second version causes the rendering of the form to show all the errors (and to call 'clean()').
With risk of having this deleted by the moderator ;) Thank you to all those who commented and for your patience with a new django developer.
Scenario: large project with many third party apps. Want to add tagging to those apps without having to modify the apps' source.
My first thought was to first specify a list of models in settings.py (like ['appname.modelname',], and call django-tagging's register function on each of them. The register function adds a TagField and a custom manager to the specified model. The problem with that approach is that the function needs to run BEFORE the DB schema is generated.
I tried running the register function directly in settings.py, but I need django.db.models.get_model to get the actual model reference from only a string, and I can't seem to import that from settings.py - no matter what I try I get an ImportError. The tagging.register function imports OK however.
So I changed tactics and wrote a custom management command in an otherwise empty app. The problem there is that the only signal which hooks into syncdb is post_syncdb which is useless to me since it fires after the DB schema has been generated.
The only other approach I can think of at the moment is to generate and run a 'south' like database schema migration. This seems more like a hack than a solution.
This seems like it should be a pretty common need, but I haven't been able to find a clean solution.
So my question is: Is it possible to dynamically add fields to a model BEFORE the schema is generated, but more specifically, is it possible to add tagging to a third party model without editing it's source.
To clarify, I know it is possible to create and store Tags without having a TagField on the model, but there is a major flaw in that approach in that it is difficult to simultaneously create and tag a new model.
From the docs:
You don't have to register your models
in order to use them with the tagging
application - many of the features
added by registration are just
convenience wrappers around the
tagging API provided by the Tag and
TaggedItem models and their managers,
as documented further below.
Take a look at the API documentation and the examples that follow for how you can add tags to any arbitrary object in the system.
http://api.rst2a.com/1.0/rst2/html?uri=http://django-tagging.googlecode.com/svn/trunk/docs/overview.txt#tags
Updated
#views.py
def tag_model_view(request, model_id):
instance_to_tag = SomeModel.objects.get(pk=model_id)
setattr(instance_to_tag, 'tags_for_instance', request.POST['tags'])
...
instance_to_tag.save()
...returns response
#models.py
#this is the post_save signal receiver
def tagging_post_save_handler(sender, instance, created):
if hasattr(instance, 'tags_for_instance'):
Tag.objects.update_tags(instance, instance.tags_for_instance)
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)