I am getting not null contraint failed error while posting a group. How should i fix it? I don't want to show the user in the api so i have not used it in the serializer fields. Do i have to compulsorily add it there?
Here is my model, serializer and APIView
class DeviceGroup(models.Model):
token = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
name = models.CharField(max_length=250, blank=False, null=False)
owner = models.ForeignKey(User, blank=False, null=False)
class DeviceGroupSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source='token', format='hex', read_only=True)
class Meta:
model = DeviceGroup
fields = ['id','name']
class DevicesGroupsAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = DeviceGroupSerializer
def get_object(self, user, token):
try:
return BaseDevice.objects.filter(owner=user).get(token=token)
except ObjectDoesNotExist:
return error.RequestedResourceNotFound().as_response()
def get(self, request, format=None):
"""
Returns a list of groups
"""
reply = {}
try:
groups = DeviceGroup.objects.filter(owner=request.user)
reply['data'] = DeviceGroupSerializer(groups, many=True).data
except:
reply['data'] = []
return Response(reply, status.HTTP_200_OK)
def post(self, request, format=None):
"""
create a new group
"""
print('request.data', request.data)
print('user', request.user)
serializer = DeviceGroupSerializer(data=request.data)
print('serializer', serializer)
if serializer.is_valid():
serializer.save()
return Response(serializers.data, status.HTTP_200_OK)
return Response(serializer.errors, status.HTTP_204_NO_CONTENT)
see this carefully, user is not in request.data:
serializer = DeviceGroupSerializer(data={
'name':request.data['name'],
'owner':request.user.id,
})
also check that the serializer allows the owner to be used
from django.contrib.auth.models import User
class DeviceGroupSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source='token', format='hex', read_only=True)
owner = serializers.PrimaryKeyRelatedField(queryset=User.objects.all())
class Meta:
model = DeviceGroup
fields = ['id','name', 'owner']
Related
I'm newbie with django. I want to create an login, signup API so I find a solution on Internet. But it's not user my own User model, it use django.contrib.auth.models import AbstractUser. I don't need some field of AbtractUser so I give it =none.
Here is my models code:
from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.fields import JSONField
from django.contrib.auth.models import AbstractUser
# Create your models here.
# class User(models.Model):
# name = models.CharField(null=False,blank=False, max_length=512)
# username = models.CharField(null=False,blank=False, max_length=512, unique=True)
# email = models.EmailField(null=False,blank=False, max_length=512, unique=True)
# password = models.CharField(null=False,blank=False, max_length=512)
# status = models.CharField(null=True,blank=True, max_length=512)
# role = models.IntegerField(null=False, blank=False, default=1)
# USERNAME_FIELD = 'username'
# REQUIRED_FIELDS = []
# def __str__(self):
# return self.username
class User(AbstractUser):
last_login = None
is_staff = None
is_superuser = None
first_name = None
last_name = None
name = models.CharField(null=False,blank=False, max_length=512)
username = models.CharField(null=False,blank=False, max_length=512, unique=True)
email = models.EmailField(null=False,blank=False, max_length=512, unique=True)
status = models.CharField(null=True,blank=True, max_length=512)
role = models.IntegerField(null=False, blank=False, default=1)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = []
def __str__(self):
return self.username
class Category(models.Model):
title = models.TextField(null=False, blank=False)
description = models.TextField(null=False, blank=False)
class Question(models.Model):
title = models.TextField(null=False, blank=False)
description = models.TextField(null=False, blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
choices = models.JSONField(null=False, blank=False)
answer = models.TextField(null=False,blank=False)
level = models.IntegerField(null=True, blank=True)
But I can't login to my Django Admin with my Superuser. I create new superuser but I got an error TypeError: User() got an unexpected keyword argument 'is_staff'
My command to create superuser: python manage.py createsuperuser
I don't understand why my model can affect to my app superuser. Anyone can explain for me and give me some solution.
Here is my code in serializer:
from django.contrib.postgres import fields
from rest_framework import serializers
from app.models import User, Question, Category
class RegistrationSerializer(serializers.ModelSerializer):
email = serializers.EmailField(max_length=50, min_length=6)
username = serializers.CharField(max_length=50, min_length=6)
password = serializers.CharField(max_length=150, write_only=True)
class Meta:
model = User
fields = ['id', 'name','email', 'username', 'password', 'role']
def validate(self, args):
email = args.get('email', None)
username = args.get('username', None)
if User.objects.filter(email=email).exists():
raise serializers.ValidationError({'email': ('Email already exists')})
if User.objects.filter(username=username).exists():
raise serializers.ValidationError({'username': ('Username already exists')})
return super().validate(args)
# def create(self, validated_data):
# return User.objects.create_user(**validated_data)
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['id', 'name', 'username', 'email', 'role']
class CategorySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Category
fields = ['id', 'title', 'description']
class QuestionSerializer(serializers.ModelSerializer):
# category = CategorySerializer(read_only=False)
class Meta:
model = Question
fields = ['id', 'description', 'category', 'choices', 'answer', 'level']
Here is my code in views:
from django.db.models import query
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import generics
from rest_framework import viewsets
from rest_framework import serializers
from rest_framework import permissions
import uuid
from app.models import User, Category, Question
from app.serializers import UserSerializer, QuestionSerializer, CategorySerializer, RegistrationSerializer
from django.shortcuts import get_object_or_404
# Create your views here.
class RegistrationAPIView(generics.GenericAPIView):
serializer_class = RegistrationSerializer
permission_classes = (permissions.IsAuthenticated,)
def post(self, request):
serializer = self.get_serializer(data = request.data)
if(serializer.is_valid()):
serializer.save()
return Response({
"RequestId": str(uuid.uuid4()),
"Message": "User created successfully",
"User": serializer.data}, status=status.HTTP_201_CREATED
)
return Response({"Errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
class ListUsersAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
def get(self, request):
listUser = User.objects.all()
info = UserSerializer(listUser, many = True)
return Response(data = info.data, status = status.HTTP_200_OK)
# def post(self, request, format=None):
# serializer = UserSerializer(data=request.data)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data, status=status.HTTP_201_CREATED)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class DetailUsersAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
def get(self,request, id):
try:
user = get_object_or_404(User, pk=id)
data = UserSerializer(user).data
return Response(data, status = status.HTTP_200_OK)
except:
return Response("Error",status = status.HTTP_404_NOT_FOUND)
def patch(self, request, id):
user = get_object_or_404(Users, pk=id)
serializer = UserSerializer(user, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class CategoryViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = CategorySerializer
queryset = Category.objects.all()
class QuestionViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = QuestionSerializer
queryset = Question.objects.all()
Thanks very much.
You will need to define your own UserManager [Django-doc] to register the user without making use of is_staff, is_superuser, etc. This manager is used to create user objects. Since you have set fields like is_staff, is_superuser, etc. to None, these are no longer model fields.
Therefore you should implement your own user manager that will no longer try to set these fields in the user model. So this means it looks like:
from django.contrib.auth.models import UserManager
class CustomUserManager(UserManager):
def create_user(self, username, email=None, password=None, **extra_fields):
return self._create_user(username, email, password, **extra_fields)
def create_superuser(self, username, email=None, password=None, **extra_fields):
return self._create_user(username, email, password, **extra_fields)
This UserManager will not add is_staff and/or is_superuser to the fields that are used. You thus assign the CutomUserManager as objects manager to the user model:
class User(AbstractUser):
# ⋮
objects = CustomUserModel()
I would like to know how can I add a new value to my request.data
this is my request.data, structure:
[{'fname': 'john', 'lname': 'Doe'}]
how can I add the age key for example
This is my whole code :
def create(self, request):
formSerializer = self.serializer_class(data = request.data)
#### look Down
request.data['master'] = self.request.user.id
#######
if formSerializer.is_valid():
formSerializer.save()
objectSerializer = TeamSerializer(Team.objects.all(), many=True)
return Response(objectSerializer.data, status =
status.HTTP_201_CREATED)
return Response(formSerializer.errors, status.HTTP_400_BAD_REQUEST)
this is my model
from django.db import models
from users.models import CustomUser
# Create your models here.
class Team(models.Model):
master = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
name = models.CharField(null=False, blank=False, max_length=255)
comment = models.CharField(null=True, blank=True, max_length=255)
i have two input fields ( name + comment ) so i need master field that's why
Here you have to not need to add mater in request.data.
Try this:
def create(self, request):
formSerializer = self.serializer_class(data = request.data)
# request.data['master'] = self.request.user.id
if formSerializer.is_valid():
formSerializer.save(master = self.request.user)
objectSerializer = TeamSerializer(Team.objects.all(), many=True)
return Response(objectSerializer.data, status =
status.HTTP_201_CREATED)
return Response(formSerializer.errors, status.HTTP_400_BAD_REQUEST)
Remove master from serializer's fields
and add this in serializer:
class MYSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='master.username',read_only=True)
class Meta:
model = MY_MODEL
fields = (OTHER_FIELDs,'username')
Source Mean??
I have been spending quite a lot of time trying to understand this error I got.
From models.py
class Company(models.Model):
name = models.CharField(max_length=100, unique=True, default="")
email = models.CharField(max_length=100, unique=True, default="")
password = models.CharField(max_length=100, unique=True, default="")
bsb = models.IntegerField(default=0)
account = models.IntegerField(default=0)
sign_up_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Payment(models.Model):
company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name="payments")
name = models.CharField(max_length=100, unique=True, default="")
bsb = models.IntegerField(default=0)
account = models.IntegerField(default=0)
created_date = models.DateTimeField(auto_now_add=True)
paid_date = models.DateTimeField(default=datetime.now() + timedelta(days=36500))
status = models.IntegerField(default=0)
and from serializers.py
from rest_framework import serializers
from .models import Payment, Company
class PaymentSerializer(serializers.ModelSerializer):
company = serializers.ReadOnlyField(source='company.name')
class Meta:
model = Payment
fields = ['company', 'name', 'bsb', 'account', 'created_date', 'paid_date', 'status']
class CompanySerializer(serializers.ModelSerializer):
payments = serializers.PrimaryKeyRelatedField(many=True, queryset=Payment.objects.all())
class Meta:
model = Company
fields = ["name", "email", "password", "payments",
"bsb", "account", "sign_up_date"]
As you can see, I have included the related_name as "payments" for company attribute in Payment class. But when I go to http://localhost:8000/bill_payer/resources/company I got the following error:
AttributeError: 'User' object has no attribute 'payments'
I have verified that my Company class do indeed have the payments class through manage.py shell.
Any idea? I am new. Here's views.py in case it is important:
class PaymentList(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get(self, request):
payments = Payment.objects.all()
serializer = PaymentSerializer(payments, many=True)
return Response(serializer.data)
def perform_create(self, serializer):
serializer.save(company=self.request.user)
class PaymentDetail(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get_object(self, pk):
try:
return Payment.objects.get(pk=pk)
except Payment.DoesNotExist:
raise Http404
def get(self, request, pk):
payment = self.get_object(pk)
serializer = PaymentSerializer(payment)
return Response(serializer.data)
def put(self, request, pk):
payment = self.get_object(pk)
serializer = PaymentSerializer(payment, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
payment = self.get_object(pk)
payment.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class CompanyList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = CompanySerializer
class CompanyDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = CompanySerializer
You get the error because you try to use User objects for CompanySerializer which expects Company model objects. It will work if you fix it as below.
class CompanyList(generics.ListAPIView):
queryset = Company.objects.all()
serializer_class = CompanySerializer
class CompanyDetail(generics.RetrieveAPIView):
queryset = Company.objects.all()
serializer_class = CompanySerializer
Please change this
class CompanyList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = CompanySerializer
class CompanyDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = CompanySerializer
to
class CompanyList(generics.ListAPIView):
queryset = Company.objects.all()
serializer_class = CompanySerializer
class CompanyDetail(generics.RetrieveAPIView):
queryset = Company.objects.all()
serializer_class = CompanySerializer
also your doing wrong here in perform_create method.
class PaymentList(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get(self, request):
payments = Payment.objects.all()
serializer = PaymentSerializer(payments, many=True)
return Response(serializer.data)
def perform_create(self, serializer):
serializer.save(company=self.request.user)
it should not be
serializer.save(company=self.request.user)
coz its not a company object. self.request.user is a user object. And you are trying to save user object to company object. its wrong.
try using
serializer.save()
or
serializer.save(company=serializer.data.get("company"))
whenever is authenticated user post in My device I've to check id the device is associated with this user or not? for that, I've get all the information using request.user, but instead I am just getting an email address, is there any solution for this?
My custom User model
class User(AbstractUser):
"""User model."""
username = None
email = models.EmailField(_('email address'), unique=True)
mobile_token = models.CharField(max_length=20,blank=True,null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager_1()
My device model
class Device(models.Model):
# user_id = models.CharField(max_length=20,primary)
device_id = models.CharField(max_length=20 ,primary_key=True )
email = models.ForeignKey(User,on_delete=models.CASCADE,blank = True,null=True)
date_added = models.DateField(default=timezone.now)
def __str__(self):
return self.device_id
My serailzers
class UserSerializer(serializers.ModelSerializer):
# my_field = serializers.SerializerMethodField()
# def get_field_name(self, obj):
# return "name"
class Meta:
model = models.User
# key= {'status':'success'}
fields = ('first_name', 'email','last_name','mobile_token',)
class DeviceSerializer(serializers.ModelSerializer):
# locations = serializers.PrimaryKeyRelatedField(many=True,
queryset=models.User.objects.all())
class Meta:
model = models.Device
fields = ('date_added','email','device_id',)
And The View for device
class DeviceView(viewsets.ViewSet):
queryset = models.Device.objects.all()
serializer_class = serializers.DeviceSerializer
def list(self,request):
queryset = models.Device.objects.all()
serializer = serializers.DeviceSerializer(queryset, many=True)
final_data = serializer.data
import json
api={}
api['data'] = final_data
api['message'] = "Device ids"
# Device_name_api = final_data[]
# validators = serializer.get_validators()
api['status'] = 1
# print(request.data)
return Response(api)
def create(self, request, *args, **kwargs):
# response = super().post(request, *args, **kwargs)
# print(self.response)
serializer = self.serializer_class(data=request.data)
print(request.user)
# user_data=models.User.objects.all()
# print(user_data)
# print(request.META['HTTP_X_MYHEADER'])
# print(request.data['device_id'])
if serializer.is_valid():
return Response({
'data':serializer.data,
'status': 1,
'message': 'Succuess'
}, status=status.HTTP_400_BAD_REQUEST)
Try to use depth option:
class DeviceSerializer(serializers.ModelSerializer):
class Meta:
model = models.Device
fields = ('date_added','email','device_id',)
depth = 1
I have a below view, serializer and model. Using BrowsableAPIRenderer i render HTML page. I need to assign current user id to user_id field and hide the same from HTML rendering(not allow to edit and enter). I am using Django rest framework 2.3.13. Kindly help me to achieve this.
serializer.py
class TagOwnerSerializer(serializers.HyperlinkedModelSerializer):
tag_id = serializers.SlugRelatedField(slug_field='tag_id')
user_id = serializers.IntegerField(write_only=True)
class Meta:
model = TagOwner
fields = ('url','tag_id','start_time','end_time','user_id')
views.py
class TagOwnerViewSet(viewsets.ModelViewSet):
"""
TagOwner table view set.
"""
model = TagOwner
queryset = TagOwner.objects.all()
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
serializer_class = TagOwnerSerializer
renderer_classes = (BrowsableAPIRenderer, JSONRenderer,JSONPRenderer,XMLRenderer,YAMLRenderer)
filter_backends = (filters.DjangoFilterBackend, filters.SearchFilter ,filters.OrderingFilter)
filter_class = TagOwnerFilter
#search_fields = ('tag_id',)
ordering_fields = '__all__'
def get_queryset(self):
user = self.request.user
if self.request.user.is_authenticated():
if not user:
return []
return TagOwner.objects.filter(user_id=user.id)
public_tags = TagReads.objects.filter(public=True).values_list('tag_id').distinct()
return TagOwner.objects.filter(tag_id__in=public_tags)
def create(self,request):
serializer = self.serializer_class(data=request.DATA)
if serializer.is_valid():
user=self.request.user.id
serializer.save(user_id = user)
return Response(serializer.data, status = status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
models.py
class TagOwner(models.Model):
user_id = models.IntegerField(blank=False,db_column='user_id',)
tag_id = models.OneToOneField('Tags',on_delete=models.CASCADE,primary_key=True,db_column='tag_id',)
start_time = models.DateTimeField(blank=True, null=True)
end_time = models.DateTimeField(blank=True, null=True)
class Meta:
managed = False
db_table = 'tag_owner'
Found it myself.
serializer.py
class TagOwnerSerializer(serializers.HyperlinkedModelSerializer):
tag_id = serializers.SlugRelatedField(slug_field='tag_id')
user_id = serializers.Field(source='user_id')
#user_id = serializers.PrimaryKeyRelatedField(read_only=True,default=serializers.CurrentUserDefault())
class Meta:
model = TagOwner
fields = ('url','tag_id','start_time','end_time','user_id')
views.py
class TagOwnerViewSet(viewsets.ModelViewSet):
"""
TagOwner table view set.
"""
model = TagOwner
queryset = TagOwner.objects.all()
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
serializer_class = TagOwnerSerializer
renderer_classes = (BrowsableAPIRenderer, JSONRenderer,JSONPRenderer,XMLRenderer,YAMLRenderer)
filter_backends = (filters.DjangoFilterBackend, filters.SearchFilter ,filters.OrderingFilter)
filter_class = TagOwnerFilter
#search_fields = ('tag_id',)
ordering_fields = '__all__'
def get_queryset(self):
user = self.request.user
if self.request.user.is_authenticated():
if not user:
return []
return TagOwner.objects.filter(user_id=user.id)
public_tags = TagReads.objects.filter(public=True).values_list('tag_id').distinct()
return TagOwner.objects.filter(tag_id__in=public_tags)
def pre_save(self, obj):
obj.user_id = self.request.user.id
This worked perfectly for me.