My target is to store data from the html form. I tried different ways, bellow way is one of them. But data is not stored in the database. What is the problem? Is the way appropriate?
views.py:
#api_view(['POST'])
def employeeListView(request):
if request.method == 'POST':
jsonData = JSONParser().parse(request)
serializer = EmployeeSerializer(data=jsonData)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, safe=False)
else:
return JsonResponse(serializer.errors, safe=False)
def InsertAndInfo(request):
if request.method == 'POST':
name = request.POST.get('name')
email = request.POST.get('email')
phone = request.POST.get('phone')
data = {
'name':name
}
headers = {'Content-Type': 'application/json'}
read = requests.post('http://127.0.0.1:8000/api/employees/',json=data,headers=headers)
return render(request, 'InsertAndInfo.html')
models.py:
class Employee(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField(max_length=30)
phone = models.IntegerField(null=True)
serializer.py:
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
fields = "__all__"
urls.py:
path('', views.InsertAndInfo, name="InsertAndInfo"),
path('employees/', views.employeeListView, name="employeeListView")
InsertAndInfo.html:
<form action="" method="POST">
<input type="text" class="form-control" name="name" id="name">
</form>
Try this...
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
#api_view(['POST'])
def employeeListView(request):
if request.method == 'POST':
serializer = EmployeeSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I changed phone = models.IntegerField(null=True) to phone = models.CharField(max_length=30, null=True),, then It worked
Related
This question might be asked alot in stackoverflow but i couldn't find the answer.
Take a look at code:
# models.py
class Message(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.CharField(max_length=200, null=True, blank=True)
room = models.ForeignKey(Room, on_delete=models.CASCADE, blank=True, null=True)
posted = models.TimeField(auto_now_add=True)
def __str__(self):
return self.body
views.py:
class RoomInsideView(View):
template_name = 'room/room_inside.html'
form_class = SendMessageForm
room = None
def get(self, request, room_id, room_slug):
self.room = Room.objects.get(id=room_id)
if self.room.is_private:
return redirect('room:private_room_auth', self.room.id)
form = self.form_class()
context = {
'room': self.room,
'form': form,
}
return render(request, self.template_name, context)
def post(self, request, room_id, room_slug):
form = self.form_class(request.POST)
if form.is_valid():
new_msg = Message(body=form.cleaned_data['body'])
new_msg.user = request.user in
all_messages = Message.objects.filter(room=self.room)
messages.error(request, 'form not valid', 'warning')
return render(request, self.template_name, {'form': form, 'message': all_messages})
forms.py:
class SendMessageForm(forms.ModelForm):
class Meta:
model = Message
fields = ('body',)
widgets = {
'body': forms.TextInput(attrs={'class': 'form-control',
'placeholder': 'Send'}),
}
template:
<form method="post" action="" novalidate>
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.body.errors }}
{{ form.body }}
<input type="submit" value="Send" class="btn btn-primary">
</form>
as I added a messages.error if form is not valid it's returning form not valid and I can't find where am I doing wrong
You always add the warning, regardless whether the form is valid or not, this does not make much sense.
That being said, you are writing too much boilerplate code, you can use a CreateView which will eliminate most of the boilerplate code:
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy
class RoomInsideView(View):
template_name = 'room/room_inside.html'
form_class = SendMessageForm
success_url = reverse_lazy('name-of-some-view')
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['room'] = get_object_or_404(Room, pk=self.kwargs['room_id'], is_private=False)
return context
def form_invalid(self, form):
messages.error(request, 'form not valid', 'warning')
return super().form_invalid(form)
def form_valid(self, form):
form.instance.room_id = self.kwargs['room_id']
form.instance.user = self.request.user
return super().form_valid(form)
The name-of-some-view should be replaced with the name of the view where the view should redirect to in case of a successful POST request, this is done to implement the Post/Redirect/Get architectural pattern [wiki].
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
view.py
#csrf_exempt
def blog_list(request):
if request.method == 'GET':
post = Post.objects.all()
serializer = BlogSerializer(post, many=True)
return JsonResponse(serializer.data,safe=False)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = BlogSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
class BlogSerializer(serializers.Serializer):
class Meta:
model = Post
fields = ['author', 'title', 'text', 'published_date']
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
First you need to understand a few things about this code
def blog_list(request):
if request.method == 'GET':
post = Post.objects.all()
serializer = BlogSerializer(post, many=True)
return JsonResponse(serializer.data,safe=False)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = BlogSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
Here request referes to a request object, which contains all the data inside the request (method, body, data, headers, etc), and not just the request data. So, you want to parse request.body, instead of request.
data = JSONParser().parse(request.body)
You should pass request.data to serializer. Passing whole request won't return anything, because request does not have fields you declared in serializer. They are in post data.
in model.py create a class in which 3 fields are there
class signUp(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
password = models.IntegerField()
in serializer.py
class SignupSerializer(serializers.Serializer):
class Meta:
model = signUp
fields = ('username', 'email', 'password')
def create(self, validated_data):
email = validated_data['email'],
name = validated_data['name'],
password = validated_data['password']
return signUp.objects.create(**validated_data)
in views.py
#api_view(['POST'])
def signup(request):
if 'username' not in request.data:
response = {'message': 'please enter username'}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
elif 'email' not in request.data:
response = {'message': 'please enter email'}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
elif 'password' not in request.data:
response = {'message': 'please enter password'}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
if request.method == 'GET':
signup = signUp.objects.all()
serializer = SignupSerializer(signup, many=True)
return JsonResponse(serializer.data, safe=False)
if request.method == 'POST':
data = JSONParser().parse(request)
serializer = SignupSerializer(data=data)
if serializer.is_valid():
user = serializer.validated_data.get('username')
message = f'successfully signup {user}'
return Response({message: message}, status=HTTP_200_OK)
All functions work and signup is a success, but after that data not show up in the database. How do I save it in the database?
I have a registration page that allows a user to sign up. After doing so, I want to call an API and then, save the data to my model (not saving it to a form though). I tried doing this:
models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, primary_key=True, related_name = 'profile')
address = models.TextField()
birthday = models.DateField()
def __str__(self):
return str(self.user)
views.py:
def signup(request):
if request.method == 'POST':
user_form = UserForm(request.POST)
register_form = RegisterForm(request.POST)
if user_form.is_valid() and register_form.is_valid():
username = user_form.cleaned_data.get('username'),
first_name = user_form.cleaned_data.get('first_name'),
last_name=user_form.cleaned_data.get('last_name'),
email=user_form.cleaned_data.get('email'),
password=user_form.cleaned_data.get('password2'),
birthday = register_form.cleaned_data.get('dob'),
address=register_form.cleaned_data.get('address'),
payload = {'username': username,'first_name': first_name,'last_name': last_name,'email':email,'password':password,'register' : {'birthday': birthday,'address': address}}
response = requests.post('http://127.0.0.1:8000/my_api/',json=payload)
return redirect("home") #re-direct if login is successful
else:
user_form = UserForm()
register_form = RegisterForm()
return render(request, 'users/register.html', {'user_form': user_form, 'register_form': register_form})
class RegisterAPI(APIView):
permission_classes = [AllowAny]
def post(self, request, format=None):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
content = {'status': 'You are registered'}
return Response(content, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
serializers.py:
from users.models import Profile
from django.contrib.auth.models import User
class ProfileSerializer(serializers.ModelSerializer):
birthday = serializers.DateField(format="%Y-%m-%d")
class Meta:
model = Profile
fields = ('birthday','address')
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = ('username','first_name','last_name','email', 'password', 'profile')
def create(self, request, validated_data, *args, **kwargs):
register_data = validated_data.pop('profile')
password = validated_data.pop('password', None)
user = User.objects.create(**validated_data)
if password is not None:
user.set_password(password)
user.save()
Profile.objects.create(user = user, **register_data)
return validated_data
However, I am getting this error:
Object of type data is not JSON serializable error in Django
It seems that it's got to do with the birthday. On my template, a user can display the date of birth as 'YYYY-MM-DD'. How can I fix this error?
The create method in your UserSerializer should return a User instance instead of validated_data.
def create(self, request, validated_data, *args, **kwargs):
register_data = validated_data.pop('profile')
password = validated_data.pop('password', None)
user = User.objects.create(**validated_data)
if password is not None:
user.set_password(password)
user.save()
Profile.objects.create(user = user, **register_data)
return user
I'm trying to create a post and update my list of posts. I currently get this error IntegrityError at /posts/create/ NOT NULL constraint failed: posts_post.publish Not sure what the error means and how to fix it. The files below are my posts/views.py, forms.py, post_forms.py and models
def posts_create(request):
# return HttpResponse("<h1> Create a posts. </h1>")
form = PostForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
context = {
"form": form
}
# if request.method == "POST":
# print("This is the content: ", request.POST.get("content"))
return render(request, "post_form.html", context)
def posts_detail(request, id):
instance = get_object_or_404(Post, id=id)
context = {
"user": instance.user,
"instance": instance
}
return render(request, "posts_detail.html", context)
def posts_list(request):
# return HttpResponse("<h1> List a posts. </h1>")
# TODO: Privacy stuff
queryset = Post.objects.all()
context = {
"object_list": queryset,
"user": "username"
}
return render(request, "post.html", context)
Models for post:
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
status = models.CharField(max_length=6, choices=Status, default=POST)
content = models.TextField()
publish = models.DateField(auto_now=False, auto_now_add=False)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
privacy = models.IntegerField(choices=Privacy, default=PUBLIC)
unlisted = models.BooleanField(default=False)
This is the post_form.html
<html>
<body>
<h3>Create Post</h3>
<form method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Share" />
</form>
</body>
</html>
This is the respective forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = [
"content"
]
from datetime import datetime
def posts_create(request):
# return HttpResponse("<h1> Create a posts. </h1>")
form = PostForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.publish = datetime.now()
instance.save()
context = {
"form": form
}
# if request.method == "POST":
# print("This is the content: ", request.POST.get("content"))
return render(request, "post_form.html", context)
do this in your view. import the first line then change your view