Create Django Model Instance using POST method in another Python Script - python

So I have a django app with some models which I can manipulate via admin and also through a client facing site, like add instances etc. However, I would like to try something a little different from that. I have a Python script that uses POST and JSON objects based on those self same models and I would like to be able to run it, connect to my django app server via a port and create new instances of my models (essentially without using Admin or my client page). Any ideas how I go about this?

If what the script does is simple, it may be easiest just to create a view which receives the JSON, processes it, and returns a JsonResponse.
e.g.
def create_object(request):
if request.method == 'POST':
data = json.loads(request.body)
# Do something with the data - e.g. create a model instance
MyModel.objects.create(**data)
return JsonResponse({'status': 'created'})
Alternatively, if the script does more complicated things or if you intended to expand it in future, you may be best to expose your site via a REST API using something such as Django Rest Framework.
With Django Rest Framework, you can fairly rapidly build CRUD based APIs around your models using components such as ModelViewSets and ModelSerializers and expose them over REST with minimal code.

Related

Convert Django Views to rest services

I have an application created long back, now client want to expose its some of views as APIs without breaking existing functionality, so that they can directly consume APIs using REST Tools to see the reports.
Is there any easier way, I can convert my function to a REST View.
P.S - I kept code shorter here to keep question simple, but in fact, its much complex in the actual app.
eg.
URL : -
`path('/users', views.show_user_details, name='users'),`
VIEW
def show_user_details(request, user_id):
users = User.objects.all()
return render(request, "Users.html", {"users":users})
In REST Views, I want it to convert its input and output so that it can be accessible with same urls(or with little modifications), without much updating the existing views.
`path('rest/users', views.show_user_details, name='users'),` #-- I am ok to add new url like this, but without much change in existing view .
def show_user_details(request, user_id):
users = User.objects.all()
return JsonResponse({"users":users})
Due to the fact that a normal website visit is still a GET request and GET is just one of your usual REST actions, you'll probably want to prepare your own independent API endpoint. Check out django-rest-framework for that, and you might just feel at home for this task.

Is it possible to create a Django app which only reads data from external database and provides REST API?

In other words - I want to create a simple Django Rest Framework app which preferable doesn't need it's own database.
This Django API app should only provide data for some external frontend app (e.g. Angular/Webpack stack).
There is no technical difference between external and the own database as pointed out by Kalus D. any database which is online and the username and password of it is known (means provided in django's setting.py) is Django's database. There can be multiple Databases of this type. so that's it.
But I don't think you mean the above. I think What you mean is collect data from external APIs or web pages e.g Wikipedia Rest API. then process that data like filter it, combine different data or anything you like and then send it to the user.
then yes it is possible but you don't need DRF for it. DRF is mainly applicable when you want to serialize your won models data. you can just send response in JSON format insted of html without using DRF.

Django REST or simple Django for REST API

I would like to know if it is possible to build a REST Api using only Django (without Django REST).
I have following code in my views.py my Django (no REST Django)
from django.http import HttpResponse, JsonResponse
def get_something(request, object = None):
dummyDict = {'Debug':object}
return JsonResponse(dummyDict)
ulrs.py
url(r'^(?P<object>\w{1,50})$', views.get-something, name = "get-something"),
Can this work as REST API?
I tried testing using curl and I get following answer from my django server:
HTTP/1.0 200 OK
Date:
Server:
X-Frame-Options:
Content-Type: application/json
{"Debug": daodoaw}
You may do that though you'll have to add a lot of things to make an API RESTfull.
Your example is already missing proper response code for PUT / POST / PATCH / DELETE and doesn't respond correctly to OPTIONS
Ofcourse you can do these things with Django, but the advantage of django rest is that it is specifically created to handle api creation and management, Thus using django rest will be much more effective. When you look at the documentation of django rest, you could see that viewsets like ModelViewSet, GenericViewSet which are capable of handling any type of requests(POST, PUT, PATCH, etc...) in a two or three line code. Meanwhile while you using django you have to specify each and every case. Its just a case where DRF is more preferred).
What I try to say is, DRF is more handy in the case of API Creation and has a very good documentation in their official website
If you have to know about any specific part, please comment below
Thanks
Using Django is not a crime! We are given the liberty to use either DRFor Django.
Here are some of the situations when you can think of using DRF:
Let's imagine, you have developed a web application with django. What would happen if your client or you want a mobile version (android/iOS version) of your application? As multi-platform development is becoming the norm, using DRF can become crucial to reuse the same backend for both a mobile app and a web app.
Another comprehensive reason to use DRF is its super easy serialization facility.
If you want to segregate your front-end from Django provided templates, you are free to use modern javascript frameworks such as Vue, React or Angular for better design and to be dynamic as much as possible with your REST APIs.
When you use DRF, you are given ready-made view classes (ApiView, GenericAPIView, Viewsets) that are only a few lines of coding and able to handle all sorts of requests such as (POST, PUT, PATCH, etc...).
NOTE: Definitely, you can use Django depending on the project you are handling. In the case of building a web application that doesn't need to be accessed from other platforms, I would not use DRF. It entirely depends on the requirements.

Multi-tenant issue using django-rest-framework

We have an issue to make a multi-tenancy SaaS application using Django and django-rest-framework.
We would like to route to the correct database according to the url, and using django-rest-framework serializers.
But with django-rest-framework, we cannot specify the database we want to save to with serializers. We are able to request data by overriding the get_queryset method, and with the using(<database>) function.
class SomeSerializer(serializers.ModelSerializer):
def get_queryset(self):
return SomeModel.objects.using(self.database)
If we want to save an instance to a custom database, we cannot use ModelSerializer, we have to write each serializer using the Serializer class.
We can make a pull request to add the option to django-rest-framework Multiple databases support #65 - django-rest-framework
Or, we can do something similar to this snippet : Database Routing by URL, it's quite old (2010) but still working. But we are not very comfortable with the idea of using the local thread to transfer variables.
How do we do this properly in 2017 ? Are there other options ?

Django, how to generate an admin panel without models?

I'm building a rather large project, that basically consists of this:
Server 1:
Ice based services.
Glacier2 for session handling.
Firewall allowing access to Glacier2.
Server 2:
Web interface (read, public) for Ice services via Glacier2.
Admin interface for Ice services via Glacier 2.
The point I'm concerned with is the web interface. I want to use Django, because it's both written in python and has that incredibly useful automatic admin panel generator.
The web interface doesn't access any database. It connects to an Ice service on Server #1 via the Glacier2 router and uses the API exposed by those services to manipulate data.
And as you probably know, the admin generation in Django depends on the use of Django's ORM; which I'm not using since I have no database to access.
So I need to generate the admin panel, but, instead of having an standard data access like the ORM normally does, I need to intercept any "db-access" calls and transform them into Ice service calls, and then take the service's output (if any), transform it into whatever the ORM normally returns and return control to Django.
Anyone knows how I could do this? what would I need to subclass? Any specific ideas?
Thanks for your time.
I think there might be a simpler way than writing custom ORMS to get the admin integration you want. I used it in an app that allows managing Webfaction email accounts via their Control Panel API.
Take a look at models.py, admin.py and urls.py here: django-webfaction
To create an entry on the admin index page use a dummy model that has managed=False
Register that model with the admin.
You can then intercept the admin urls and direct them to your own views.
This makes sense if the add/edit/delete actions the admin provides make sense for your app. Otherwise you are better off overriding the admin index or changelist templates to include your own custom actions
The real power of the contrib.admin is django Forms. In essence, the admin tool is basically auto-generating a Form to match a Model with a little bit of urls.py routing thrown in. In the end it would probably just be easier to use django Forms apart from the admin tool.
you can "mock" some class so it look like a model but it does proxy to your APIs
f.e.
class QuerysetMock(object):
def all():
return call_to_your_api()
[...]
class MetaMock(object):
def fields():
return fields_mock_objects..
verbose_name = ''
[...]
class ModelMock(object):
_meta = MetaMock()
objects = QuerysetMock()
admin.site.register(ModelMock)
This may work.. but you need to do a lot django.model compatible stuff
The django ORM has a pluggable backent, which means that you can write a backend for things that aren't RDBMSes. It's probably a rather large task, but a good place to get started is with Malcolm Tredinnick's talk from DjangoCon 2008, Inside the ORM.
Otherwise, you could bypass the ORM altogether, and write the forms manually for the access you need.

Categories