3

Here is how my views.py method looks like:

def save(request):
    if request.method == 'POST':
        post = json.loads(request.body)
        post['id'] = int(post['id'])
        post['desc'] = post['description']
        ....
        ....
    return HttpResponse(json.dumps({'message': message, 'saved_item': saved_id}))

Now I have a requirement to call this save method from outside the django project directory. I believe this can be done by importing this views.py file somehow but I'm not sure how to provide request as a parameter to this method.

Also this save method does some interaction with models.py file as well, to save an item into db.

4
  • 1
    What do you want to accomplish? I seriously doubt you “have a requirement to call this method”. More likely, you have a requirement to get something done. I guess you want to save some data, what form does it have? The view is intended to process an HTTP request. You are not processing one, so you should not be using it. Commented Nov 17, 2015 at 8:49
  • 2
    Alternatively from falsetru's answer, and based on the comment by spectras, I would recommend you to decouple the functionality in your view function to a separate function. Then you can call this from other Python code. Commented Nov 17, 2015 at 8:59
  • @spectras Sebastian's answer describes what I wanted to accomplish. The save method contains some python code to perform some tasks, yes I wanted to save some data and make use of reusability. I could have written the same code again, that'd have introduced Repetition code. Being a python programmer one should respect DRY (en.wikipedia.org/wiki/Don't_repeat_yourself) Commented Nov 17, 2015 at 15:09
  • @Napstar unless you are building a testcase, the method described by Sebastian should not be used. Instead, you should extract the tasks from you view. Create a function called, say do_save_tasks. You can then use this function from both your external code and your view. That way it's DRY and you do not misuse Django testing facility. Commented Nov 17, 2015 at 17:07

3 Answers 3

2

Caution

This code will

  1. load the Django testing facility,
  2. create a request mockup that you must fill by
  3. serializing the data, only to have
  4. the view deserialize it just after, handle it
  5. serialize the result, which you must
  6. extract for the response
  7. deserialize again.

Unless you are building a testcase for the view, this is a hack, and an ugly one.

You can use [django.test.RequestFactory][1] to instanciate a request instance:

from django.test import RequestFactory
from myapp import save

self.factory = RequestFactory()
request = self.factory.get('/customer/details')
request = self.factory.post('/customers/',{"name":"alfred"})
save(request)

This is often very useful for tests.

Sign up to request clarification or add additional context in comments.

4 Comments

I'll add the exact same comment I had put on a since-deleted answer: do not do that. This will 1) load the Django testing facility, 2) create a request mockup that you must fill by 3) serializing the data, only to have 4) the view deserialize it just after, handle it, then 5) serialize the result, which you must then 6) extract for the response and 7) deserialize again. Unless you are building a testcase for the view, this is a hack, and an ugly one.
whats your point though? It's probably a bad idea, but this is an answer about the implementation rather than the design. If you think this answer could be improved please leave a comment.
It's just that when asked how to shoot oneself in the foot, I tend to value answers that explain why it is a bad idea and how it can be avoided, over answers that go like “here is the gun, here is the trigger, point at your foot and pull”. Even though that's technically a correct answer. At least it should come with huge warnings on it.
Not under all circumstances is this a hack. I have an application where a user can (for testing purposes) interactively submit a JSON object like an external customer system would normally do. I want this to behave as much as a real external call as possible and therefore using the test client is a fully appropriate approach.
2

Growing my comments into a more detailed case. Your views will usually look like this:

def my_view(request):
    data = deserialize_data_from_request(request)
    result = do_something_with_data(data)
    return serialize_result_into_response(result)

What you want, I believe, is to do_something_with_data from outside your project directory. You have two ways to achieve this, without repeating yourself:

1) The hackish way.

You are not handling an HTTP request, so you:

  • fire up Django testing tools
  • create a request mockup
  • serialize your data into the request mockup
  • call your view on the request mockup
    • your view deserializes_data_from_request
    • your view does_something_with_data
    • your view serializes_result_into_response
  • extract the serialized result from the response
  • deserialize the result

Although it works, it is definitely kludgy and convoluted. The only reason to do this is when building view testcases, since then you actually want to test the deserialization/serialization processes.

See Sebastian Wozny's answer to do this.

2) The clean way.

Extract the task from the view. Change your view module in this way:

def my_save_function(data):
    return do_something_with_data(data)

def my_view(request):
    data = deserialize_data_from_request(request)
    result = my_save_function(data)
    return serialize_result_into_response(result)

Now, from your external code, you can directly invoke my_save_function. No need to load Django testing facility. No need to serialize/deserialize your data several times.

1 Comment

I have the same requirement as OP and already have that "store some data" function separate. But when I try to import the view I get the error django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. On the GUI the Django app works fine.
1

You could run the server as usual. And from your other python program, do a HTTP-(POST) request to this view.

I recommend this library, it is really easy to use: http://docs.python-requests.org/en/latest/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.