Saving data to Postgres DB using django rest framework - python

I'm new in django development. I m developing an API in which i am sending data from client side (mobile app) and this data is to be stored in a database using django. And if I query the data the data should be fetched from the DB. Database is preferably postgres/mysql DB. I have written some part of the code but stuck how to proceed. I'll appreciate if someone can guide me how to proceed.
from django.shortcuts import render
from rest_framework.views import APIView
from django.http import Http404
from django.http import JsonResponse
from django.core import serializers
from django.conf import settings
import json
# Create your views here.
#api_view(["POST"])
def getIdealWeight(heightData):
try:
height=json.loads(heightData.body)
weight=str(height*10)
return JsonResponse("the ideal weight is:"+weight+" kg.",safe=False)
except ValueError as e:
return Response(e.args[0],status.HTTP_400_BAD_REQUEST)

Judging from the code, I'll advice you start from the very beginning of DRF Tutorials and cover a great part of it before going further with your project. After the quickstart, you should visit the individual parts dedicated to the major concepts like serializers, views, etc. Jumping straight to the project without having a fair knowledge of the framework will make it difficult to achieve what you want.

Related

Where to best execute database operations using Django framework?

Thanks in advance for any help. I am new to django specifically as well as web development in general. I have been trying to teach myself and develop a website using the Django framework and while everything is working so far, I am not sure if I am really doing things in the best possible way.
Typically, within my django app, I will have certain points where I want to modify the contents of my database model in some way. A typical use case is where I have button on my site that says "Add a post":
models.py:
from django.db import models
# data model import
from django.contrib.auth.models import User
# Create your models here.
class Post(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
post = models.CharField(max_length=1024)
urls.py:
from django.urls import include, path
from . import views
urlpatterns = [
path('', views.post, name='new_post'),
path('post_exec', views.post_exec, name='post_exec'),
]
views.py:
from django.contrib import messages
from django.shortcuts import render, redirect
# import data models
from django.contrib.auth.models import User
from .models import Post
def post(request):
# make sure the user has privileges
user = User.objects.get(id = request.user.id)
if not user.is_superuser:
return redirect('home')
return render(request, 'post.html')
def post_exec(request):
# make sure the user has priveledges
user = User.objects.get(id = request.user.id)
if not user.is_superuser:
return redirect('home')
# create the post
new_post = Post.objects.create()
new_post.user = user
new_post.post = request.POST['post']
new_post.save()
# this could redirect to a confirmation page or something too
return redirect('home')
You can see what I am doing here is that everytime I need a change to the database due to user input, I am executing the code to do the requested database change in a django view and then redirecting to another page following completion of the database change. While this works, it feels kind of clunky (you end up needing pages that you never actually use), it seems pretty sketchy in terms of security (although I am checking for credentials on each page), and I imagine there is a better way to do this.
Can any experience Django developers offer some advice for how I should be best structuring my project for these specific types of common database operations?
The Django's views is a good place to organize the project's CRUD system so users can manage their data. You can use the class-based views to group the GET, POST etc requests. Also there are better ways of using the authorization system with the login_required() decorator, the LoginRequiredMixin class and other solutions that you can rich here

save() doesn't work in Mongoengine

I'm trying to perform a simple insert operation using Mongoengine and Django.
Regarding my project structure simply I have a project, AProject and an app, AnApp. I have a running mongo in a remote machine with an IP of X.X.X.X. I am able to insert document using Robomongo in it.
I have removed the default Database configuration part of the settings.py located inside the AProject directory. The newly added lines are shown below:
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
import mongoengine
# ----------- MongoDB stuff
from mongoengine import register_connection
register_connection(alias='default', name='AProject', host='X.X.X.X')
# ----------
Now let me show the models.py and the views.py located inside AnApp.
models.py
from mongoengine import Document, StringField
class Confession(Document):
confession = StringField(required=True)
views.py
from django.http import HttpResponse
from models import Confession
from mongoengine import connect
def index(request):
connect('HacettepeItiraf', alias='default')
confession = Confession()
confession.confession = 'First confession from the API'
print(confession.confession + ' Printable') # The output is --First confession from the API Printable--
print(confession.save()) # The output is --Confession object--
return HttpResponse(request)
The urls.py located inside AProject is simply as below:
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^confessions/', include('confession.urls')),
url(r'^admin/', admin.site.urls),
]
When I enter http://127.0.0.1:10000/confessions/ I see a blank screen which I expect. However there is nothing saved from the API. I get the expected output except Confession object.
How can I solve this problem?
EDIT:
I found the concrete proof that currently MongoEngine's support for Django is unstable and it is corresponding to Django version 1.9:
MongoEngine documentation on Django support states:
Django support has been split from the main MongoEngine repository. The legacy Django extension may be found bundled with the 0.9 release of MongoEngine.
and
6.1. Help Wanted!
The MongoEngine team is looking for help contributing and maintaining a new Django extension for MongoEngine! If you have Django experience and would like to help contribute to the project, please get in touch on the mailing list or by simply contributing on GitHub.
Which leads to this repo, where the following is stated:
THIS IS UNSTABLE PROJECT, IF YOU WANT TO USE IT - FIX WHAT YOU NEED
Right now we're targeting to get things working on Django 1.9
So it may be possible that it cannot play well with Django at this state or with your version and thus the problem occurs.
Initial attempt, leaving it here for legacy reasons.
I believe that the problem occurs on how you are initializing your object, although I do not have a set up to test this theory.
It is generally considered that is better to make a new object with the .create() method:
def index(request):
connect('HacettepeItiraf', alias='default')
confession = Confession.objects.create(
confession='First confession from the API'
)
print(confession.confession + ' Printable')
confession.save()
return HttpResponse(request)
Have a look at the Django & MongoDB tutorial for more details.
In this tutorial, the supported Django version is not mentioned, but I haven't found concrete proof that MongoDB Engine can or can't play well with Django version > 1.8.
Good luck :)

How to send json from django view and receive it on HTML

I am working on GIS project using GeoDjango and for this I have to render a map using OpenLayers. My snippet accepts JSON to create layers in OpenLayers. I want to send my "Administrative" model of GeoDjango as JSON to my HTML page and receive it on HTML as JSON to render my map.
Please give another suggestion also about how to render my GeoDjango Model in an OpenLayers map.
My adminstrative model:
class UPAdministrative(models.Model):
name=models.CharField(max_length=51)
admin_leve=models.CharField(max_length=5)
ls=models.LineStringField()
objects=models.GeoManager()
def __unicode__(self):
return self.name
I think you have to implement CRUD to your models and use it in html. For displaying geoobject I only used django admin page.
To write a CRUD see
tastypie
Django REST framework
You can serialize your model to a format supported by OpenLayers in a view. For example, this view sends just the geometry as geojson:
from django.http import HttpResponse
from models import UPAdministrative
def upadministrative_geometry_json(request, upadmin_id):
up_admin = UPAdministrative.objects.get(pk=upadmin_id)
geojson = up_admin.ls.geojson
return HttpResponse(geojson, mimetype='application/json')
The question Rendering spatial data of GeoQuerySet in a custom view on GeoDjango has a more detailed example of how to integrate data with OpenLayers.

Writing a file upload API using Django

I have a Django app that revolves around users uploading files, and I'm attempting to make an API. Basically, the idea is that a POST request can be sent (using curl for example) with the file to my app which would accept the data and handle it.
How can I tell Django to listen for and accept files this way? All of Django's file upload docs revolve around handling files uploaded from a form within Django, so I'm unsure of how to get files posted otherwise.
If I can provide any more info, I'd be happy to. Anything to get me started would be much appreciated.
Create a small view which accepts only POST and make sure it does not have CSRF protection:
forms.py
from django import forms
class UploadFileForm(forms.Form):
title = forms.CharField(max_length=50)
file = forms.FileField()
views.py
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.http import HttpResponse, HttpResponseServerError
# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file
#csrf_exempt
#require_POST
def upload_file(request):
form = UploadFileForm(request.POST, request.FILES)
if not form.is_valid():
return HttpResponseServerError("Invalid call")
handle_uploaded_file(request.FILES['file'])
return HttpResponse('OK')
See also: Adding REST to Django

Django RSS Feed Authentication

I am looking into adding RSS feeds to one of my Django apps and I would like to be able to have them be authenticated.
I want to use the new syndication framework in Django 1.2. I've read the docs on how to do this and have the basic feeds setup.
I am new to authenticating feeds, so I am not sure what the best approach to take is or what my options really are.
Each user has a unique sub domain and I would like the URL structure to look something like this: http://mysubdomain.mysite.com/myapp/rss/ if possible.
I don't want the feeds to be publicly available, is it possible to use the users username and password for the authentication? Have you found that most feed readers support this? If it's not possible to authenticate for each user, should I try to use a uuid to give them a unique url or is that not secure enough?
As you can probably tell I am not sure what direction to take with this, so any advice on the best way to do this would be very much appreciated.
Thanks
This is an old thread, but I recently encountered the same question. I solved it by overloading the __call__ method of the Feed object:
from django.http import HttpResponse
class ArticleFeed(Feed):
"snip [standard definitions of title, link, methods...]"
def __call__(self,request,*args,**kwargs):
if not request.user.is_authenticated():
return HttpResponse(status=401)
else:
return super().__call__(request,*args,**kwargs)
Have you tried wrapping the syndication view django.contrib.syndication.views.feed into a view that requires login? RSS feeds should normally be fetched over HTTP, so this should work!
# Import Django's standard feed view.
from django.contrib.auth.decorators import login_required
from django.django.contrib.syndication.views import feed
# Wrap it in a new feed view that requires authentication!
private_feed = login_required(feed)
Caveat: I've never tried this!
Edit!
To be safe with RSS readers that don't support redirection, return a HTTP 401 status code with the following:
authentication_url = '/accounts/login'
def feed_safe_login_required ( view ):
def _ ( request, *args, **kwargs ):
if not request.user.is_authenticated:
return HttpResponseNotAuthorized, authentication_url
return _
feed = feed_safe_login_required(django.contrib.syndication.views.feed)
Where HttpResponseNotAuthorized is as defined in this django snippet.

Categories