Im working on django rest framework and using a function based views. Im using 2 functions, one to render html and another for json response. How can I combine both the function to have more effecient code
My code
def register(request):
return render(request, 'register.html')
#api_view(['POST'])
#permission_classes((AllowAny,))
def create_user(request):
if request.method == 'POST':
serializer = SignupSerializer(data=request.data)
print 'ser'
print serializer
if not serializer.is_valid():
return Response(serializer.errors,\
status=status.HTTP_400_BAD_REQUEST)
else:
serializer.save()
return Response({
'status': 'Created',
'message': 'Verification email has been sent to your email. Please verify your account.'
}, status=status.HTTP_201_CREATED)
This can be handled by your serializer, as described in part2 of the drf tutorial.
It works like this:
urls.py
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from your_app import views
urlpatterns = [
url(r'^blahblah/$', views.create_user),
]
urlpatterns = format_suffix_patterns(urlpatterns)
views.py
def create_user(request, format=None): # add this format argument
...
Based on the format argument, you can decide you want to the request to be rendered.
Related
I am not able to render otmp.html in route "/" as if is redirecting to otp route.
flask code
from flask import Flask, request, render_template,url_for,redirect
parties=["A","B","C","D"]
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('home.html')
#return render_template('admin.html')
#app.route('/', methods=['GET','POST'])
def my_form_post():
if request.method == "POST":
adhar_no = request.form['aadhar_num']
return redirect(url_for('verification',adhar_no=adhar_no))
return render_template('otp.html')
#app.route('/otp',methods = ['POST','GET'])
def verification():
a_no=request.args.get('adhar_no')
otp_text = request.form['otp']
return render_template('party.html',n_party=parties,n=len(parties))
can anyone please help me with how to return redirect and render html page in a same route.
You can't have two routes that have the same path and method . The first route will always be called and the second one won't be reached. So to solve your problem please change one of the routes path
Note: I see the first route to be unnecessary just remove it and use this code instead
from flask import Flask, request, render_template,url_for,redirect
parties=["A","B","C","D"]
app = Flask(__name__)
#app.route('/', methods=['GET','POST'])
def my_form_post():
if request.method == "POST":
adhar_no = request.form['aadhar_num']
return redirect(url_for('verification',adhar_no=adhar_no))
return render_template('home.html')
....
I am kind of new to API.
I am working on a project where I can send POST and GET requests to different APIs. I just want to know how sort of the class in the view file should look like.
For example, I have a class that inherits generics.GenericAPIView. How do I send a get request to a specific URL or how do I save the data using the serializer to the database with post request?
class ArticelViewSet(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin):
serializer_class = ArticleSerializer_Modelserializers
queryset = Article.objects.all()
lookup_field = 'id'
def get(self, request, id=None):
if id:
return self.retrieve(request)
else:
return self.list(request)
def post(self, request):
return self.create(request) #return the created object
I am relatively new to Django and do not understand it in depth. For some reason even though everyone says that Django documentation is amazing, I do not understand it what so ever.
For some reason, I am not able to integrate a model, model and a view from 2 different apps into my home.html page.
What I am trying to do is to get a newsletter sign up, as a form. It is inside jobs app Jobs also include "Jobs" which I display on the home page and blog posts which I also want to display on my HTML home page.
I do not see a need to create a new app as it's not a model which I will be reusing a lot and ready solutions are not to my liking due to limitations.
I have tried to solve what is the problem and I finally realised that it's in the url.py file under urlpatterns.
Here are my code snipets:
project url.py
from django.conf import settings
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
import jobs.views
import blog.views
import compound.views
from django.conf.urls import url, include
from markdownx import urls as markdownx
urlpatterns = [
path('admin/', admin.site.urls),
path('', blog.views.all_blogs_on_home, name='home'),
path('blog/', include('blog.urls')),
path('', include('jobs.urls')),
path('compound/', compound.views.index),
url(r'^markdownx/', include(markdownx))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
blog urls.py
from django.urls import path
from . import views
from . import models
from django.conf.urls import url
urlpatterns = [
path('', views.allblogs, name='allblogs'),
path('<int:blog_title>/', views.detail, name='detail'),
]
This is how I combined 2 apps together before:
blog/views.py :
def all_blogs_on_home(request, template='jobs/home.html'):
context = {
'blogs': Blog.objects.all().order_by('-pub_date'),
'jobs': Job.objects.all(),
'get_email': get_email,
}
return render(request, template, context)
And this what I have for my views (the only way I found to integrate newsletter without creating a new app):
jobs/views.py :
def home(request):
jobs = Job.objects
return render(request, 'jobs/home.html', {'jobs': jobs})
def get_email(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = SignupForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/email-field/')
# if a GET (or any other method) we'll create a blank form
else:
form = SignupForm()
return render(request, 'jobs/home.html', {'form': form})
In home.html I simply add this:
{{ form }}
If I understand it correctly, you want to render two lists of models and a form using all_blogs_on_home view and jobs/home.html template.
To achieve that you should have something like this:
def all_blogs_on_home(request, template='jobs/home.html'):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
# Put form handling code here
return HttpResponseRedirect('/email-field/')
# if a GET (or any other method) we'll create a blank form
else:
form = SignupForm()
context = {
'blogs': Blog.objects.all().order_by('-pub_date'),
'jobs': Job.objects.all(),
'form': form,
}
return render(request, template, context)
In your template jobs/home.html just render blogs and jobs as before. And you can use {{ form.as_p }} or {{ form }} to render your form. Don't forget to add /email-field/ url to one of your urls.py files.
I have a Django REST Registration page with two additional boxes (first_name and last_name). The registration page works fine when I use the input boxes but when I try to do a POST to the Register page, I constantly get that the form is invalid. Upon inspection, it looks like only the first_name and last_name are in the cleaned_data, but the JSON I am posting through Postman looks like:
{
"email": "test#test.com",
"first_name": "test",
"last_name": "test",
"password1": "testtest",
"password2": "testtest"
}
and it's not just Postman, I have also been trying the same thing in an Android app via Volley. I can't figure out why some of the JSON isn't going through.
Here is my views.py for the Register page:
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import authenticate, login, models
from userauth.templates.registration.forms import RegistrationForm
from rest_framework.authtoken.models import Token
from django.views.decorators.csrf import csrf_exempt
from rest_framework.response import Response
from rest_framework.decorators import api_view, renderer_classes
from django.http import *
def index(request):
return render(request, 'userauth/index.html')
#csrf_exempt
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
print(form.data)
if form.is_valid():
print('form valid')
form.save()
username = form.cleaned_data['email']
password = form.cleaned_data['password1']
user = authenticate(username=username, password=password)
login(request, user)
token = Token.objects.create(user=user)
responseData = {
'token': str(token),
}
return JsonResponse(responseData)
else:
print('form not valid')
print(form.cleaned_data)
raise Http404
else:
form = RegistrationForm()
form = RegistrationForm()
context = {'form' : form}
return render(request, 'registration/register.html', context)
and here is my forms.py for the page where it's supposed to add the extra blanks:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = (
'email',
'first_name',
'last_name',
'password1',
'password2'
)
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.username = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
Another weird thing... Sometimes, the Register page will work on Postman if I use their built in formatter:
but not when I'm using raw JSON:
Am I just formatting the JSON wrong? How does Postman format their POST requests? Any help is appreciated... Thanks
if you dont want to move to DRF you may try altering existing code as below
#csrf_exempt
def register(request):
if request.method == 'POST':
form_data=json.loads(request.body)
form = RegistrationForm(data=form_data)
print(form.data)
if form.is_valid():
pass
My environment is :
1. server is apache 2.4
2. python 3.3, django 1.6
3. windows
django's views.py:
import simplejson as json
from django.views.generic import View
from django.views.decorators import csrf_exempt
from django.contrib import auth
from django.http import HttpResponse
class LoginFormView(View):
template_name = 'game/login.html'
#csrf_exempt
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {})
def post(self, request, *args, **kwargs):
if request.is_ajax():
username = request.POST['input_username']
password = request.POST['input_password']
user = auth.authenticate(username=username,
password=password)
payload = {}
if user is not None and user.is_active:
auth.login(request, user)
payload['msg'] = 'successful login'
else:
payload['msg'] = 'login failed'
return HttpResponse(json.dumps(payload),
mimetype = 'application/json')
else:
return HttpResponse("Error: Request is not through ajax")
My js file is:
$(document).ready(function() {
$('#submit_btn').bind('click', function(){
$.ajax({
url: "/game/login/",
data: $('#login_form').serialize(),
dataType: "json",
type: "POST",
success: function(data){
console.info(data);
//do some things
}
})
})
})
My problem is :
django can get the username and password, user can pass the authentication, I want to return some message to the client, but the js code can't get the json data from django, in the firebug, the json data contains a record {“status”: "success"} or {“status”: "failure"}, I don't know where the {“status”: "success"} comes from ,I can't get the custom message, firebug always show me the "undefined". Is the Easyui's code problem?
I need your help, thanks very much!
I got the answer.
The reason is mod_wsgi's running mode.
If use mod_wsgi's embeded mode, django's code is kept in RAM, the purpose is to improve speed. So once django's code is changed, we have to restart apache's http service.To avoid the situatioin, we could use mod_wsgi's deamon mode.