Rest Framework Django - Disable field to accept null values - django

Rest Framework Django - Disable field to accept null values
How can I configure for the serialized Model to accept blank fields?
Warning
{"Operacao": ["This field can not be blank."]}
Model
class SEF(models.Model):
operacao = models.CharField(max_length=10, null=True)
documento = models.CharField(max_length=50, null=True)
user = models.ForeignKey(User)
Serializer
class SEFCreateSerializer(serializers.ModelSerializer):
class Meta:
model = SEF
fields = ('operacao', 'documento', 'user')
View
sef_create = SEFCreateSerializer(data=data, many=True)
if sef_create.is_valid():
sef_create.save()
salvo = HTTP_200_OK
else:
salvo = sef_create.errors

Include allow_blank=True in the field definition as this:
operacao = serializers.CharField(allow_blank=True, allow_null=True)

class SEFCreateSerializer(ModelSerializer):
class Meta:
model = SEF
fields = ('operacao', 'documento', 'user')
extra_kwargs = {'operacao': {'required': False}}

You can set default value like
operacao = models.CharField(max_length=10, default=0)
if you specify a field in model like this it will take default value as 0 if nothing is present.
or in serializer
operacao = serializers.CharField(allow_null = True)

Related

Django Rest Framework Serializer - return related field

I have a model with a one-to-one relationship with a main model:
class User(models.Model):
id = models.BigIntegerField(primary_key=True)
username = models.CharField(max_length=100, blank=True)
class AggregatedStats(models.Model):
user_id = models.ForeignKey('User', on_delete=models.DO_NOTHING, unique=True)
followers_30d = models.BigIntegerField(blank=True)
I have written the following serializers:
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'followers']
class AggregatedStatsSerializer(serializers.HyperlinkedModelSerializer):
username = UserSerializer(source='user.username')
class Meta:
model = AggregatedStats
fields = ['followers_30d', 'username']
I am trying to return the username from the User model, but whatever I try to get it, the best I can do is get the hyperlinked related field from user, but not the actual "username" attribute. How would you return this?
You can simply create a field and return it:
class AggregatedStatsSerializer(serializers.HyperlinkedModelSerializer):
username = SerializerMethodField()
class Meta:
model = AggregatedStats
fields = ['followers_30d', 'username']
def get_username(self, obj):
return obj.user_id.username

How to create a custom list field when using Django Rest Framework

I have the following model and I would like to add a custom field called choices which will be a list of choices.
class HPIQuestionBank(models.Model):
label = models.CharField(
max_length=200,
db_index=True,
blank=True,
null=True)
template = models.ForeignKey(
HPIFilter, blank=True, null=True, on_delete=models.CASCADE, default='')
I have implemented the following in the serializers.
class CheckBoxesListField(serializers.ListField):
child = serializers.CharField(allow_null = True, allow_blank=True)
class TemplateQuestionBankSerializer(serializers.ModelSerializer):
answer_type = serializers.CharField(allow_null = True, allow_blank=True)
checkboxes = CheckBoxesListField()
hpianswers_set =TemplateAnswerSerializer(many=True)
class Meta:
model = HPIQuestionBank
fields = ['id','label','hpianswers_set','answer_type','checkboxes']
I'm using the serializer on my GET method. When I attempt to make a request I get the following error:
AttributeError at /api/clinic2/history/template/6/
Got AttributeError when attempting to get a value for field `checkboxes` on serializer `TemplateQuestionBankSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `HPIQuestionBank` instance.
Original exception text was: 'HPIQuestionBank' object has no attribute 'checkboxes'.
If you need to read data only you can try:
class Meta:
model = HPIQuestionBank
fields = ['id','label','hpianswers_set','answer_type',]
read_only_fields = ['checkboxes',]
Or you can work with SerializerMethodField as
class TemplateQuestionBankSerializer(serializers.ModelSerializer):
answer_type = serializers.CharField(allow_null = True, allow_blank=True)
checkboxes = SerializerMethodField()
def get_checkboxes(self, instance):
return CheckBoxesListField(instance).data

django queryset annotate all field in childtable

models.py
class Userinfo(models.Model):
useruid = models.BigAutoField(db_column='UserUID', primary_key=True)
useremail = models.CharField(
db_column='UserEmail', unique=True, max_length=100)
userpassword = models.CharField(db_column='UserPassword', max_length=128)
passwordsalt = models.CharField(db_column='PasswordSalt', max_length=128)
class Meta:
managed = False
db_table = 'userinfo'
class Postinfo(models.Model):
postuid = models.BigAutoField(db_column='PostUID',primary_key=True)
useruid = models.ForeignKey(
'Userinfo', db_column='UserUID', on_delete=models.CASCADE)
content = models.TextField(db_column='Content')
class Meta:
managed = False
db_table = 'postinfo'
if i get userlist and user's last post
i think use annotate
models.Userinfo.objects.all().annotate(lastpost="??").order_by("-useruid")
what values in "??"
like this form
[{userinfo1,"lastpost":{postinfofields}},{userinfo2,"lastpost":{postinfofields}},{userinfo3,"lastpost":{postinfofields}}]
can i this query not use forloop?
Serializer.py
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Postinfo
fields = ('postuid','content')
class UserSerializer(serializers.ModelSerializer):
lastpost = PostSerializer()
class Meta:
model = Userinfo
fields = ['useruid', 'useremail', 'lastpost']
view.py
userinfos = models.Userinfo.objects.all().order_by("-useruid")
result = UserSerializer(userinfos,many=True)
print(result.data)
raise Exception
Got AttributeError when attempting to get a value for field `lastpost` on serializer `UserSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Userinfo` instance.
Original exception text was: 'Userinfo' object has no attribute 'lastpost'.
if i add read_only=True print this
[OrderedDict([('useuid', 1), ('useremail', 'test')]), OrderedDict([('useruid', 2), ('useremail', 'test2')])]
You can use model's property for this:
class Userinfo(models.Model):
useruid = models.BigAutoField(db_column='UserUID', primary_key=True)
useremail = models.CharField(
db_column='UserEmail', unique=True, max_length=100)
userpassword = models.CharField(db_column='UserPassword', max_length=128)
passwordsalt = models.CharField(db_column='PasswordSalt', max_length=128)
#property
def lastpost(self):
return self.postinfo_set.latest('postuid')
Now you dont need annotation, just use it for example in template like this:
{{ user.lastpost.content }}
UPD
To serialize property with ModelSerializer just add serializer's field 'lastpost':
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Postinfo
fields = ('postuid','content')
class UserSerializer(serializers.ModelSerializer):
lastpost = PostSerializer()
class Meta:
model = Userinfo
fields = ['useruid', 'useremail', 'lastpost']
UPD2
You can also implement logic directly on the serializer level, without model's property. Just use SerializerMethodField:
class UserSerializer(serializers.ModelSerializer):
lastpost = SerializerMethodField()
class Meta:
model = Userinfo
fields = ['useruid', 'useremail', 'lastpost']
def get_lastpos(self, obj):
last = obj.postinfo_set.latest('postuid')
serializer = PostSerializer(last)
return serializer.data

related objects queries django rest framework

I have the following models
class STUser(AbstractBaseUser):
email = models.EmailField(unique=True)
name = models.CharField(max_length=255)
companyname = models.CharField(max_length=200, blank=True, null=True)
...
class VenuePermissions(models.Model):
user = models.ForeignKey(STUser, on_delete=models.CASCADE)
venue = models.ForeignKey(Venue, on_delete=models.CASCADE)
signupvaildatestring = models.CharField(max_length=200, blank=True, null=True)
...
I want to grab all the STUser objects and grab all their permissions.
So what I would like is to grab all the VenuePermissions objects. And grab the user and venue object of each venuePermission
Two ways I can do this. use the VenuePermissions_set attribute on STUser but then how do I grab the venue when its just going to be a pk value?
Or focus on the VenuePermissions objects and grab the user and venue from the pk values but how?
I remember nested queries, and I kinda did one in my browse code.
here is an example:
rooms = Room.objects.filter(venue=OuterRef('pk'), sixtyroundseatingoption= True)
venuelist = venuelist.annotate(sixtyrounds=Exists(rooms))
venuelist = venuelist.filter(Q(sixtyrounds = True) | Q(fullbuyoutsixtyroundseatingoption = True))
I've done the set objects in a serializer before
Example serializer:
class RoomAndImageSerializer(serializers.ModelSerializer):
roomimage_set = RoomImageSerializer(many=True, read_only=True)
class Meta:
model = Room
fields = ('pk','name')
any help with this query would be appreciated!
So this is what I am currently trying, I will post an answer if this works:
class VenueUserList(ListAPIView):
serializer_class = VenueUserListSerializer
queryset = VenuePermissions.objects.select_related('user').select_related('venue').filter(signupvaildatestring=None)
class VenueUserListSerializer(serializers.ModelSerializer):
user = UserSerializer()
venue = VenueSerializer()
class Meta:
model = VenuePermissions
fields = ('user', 'venue', 'isvenueviewer', 'isvenueeventplanner', 'isvenueadministrator')
Here is the answer. However I still need to group venues by user. Working on that.
class VenueUserList(ListAPIView):
serializer_class = VenueUserListSerializer
queryset = VenuePermissions.objects.select_related('user').select_related('venue').filter(signupvaildatestring=None)
class VenueUserListSerializer(serializers.ModelSerializer):
user = UserSerializer()
venue = VenueSerializer()
class Meta:
model = VenuePermissions
fields = ('user', 'venue', 'isvenueviewer', 'isvenueeventplanner', 'isvenueadministrator')

How to use a model field for multiple models in Django Rest Framework

I have a model BstUserActionLog with a foreign key to Django model User. I have another model for user profile information, BstUserProfile. When I do serialize BstUserActionLog with ModelSerializer I do have Django User info serialized as it is supposed to be. But I also need to add BstUserProfile serialized using the same user_id used for User model.
How can I serialize BstUserActionLog with model User and BstUserProfile are both serialized?
From my models.py:
class BstUserActionLog(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User)
bst_action_type = models.ForeignKey(BstActionType)
action_date = models.DateTimeField(auto_now_add=True)
bst_book = models.ForeignKey(BstBook)
new_value_id = models.IntegerField(blank=True, null=True)
old_value_id = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'bst_user_action_log'
class BstUserProfile(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, unique=True)
website = models.CharField(max_length=200)
picture = models.CharField(max_length=100)
is_avatar_uploaded = models.BooleanField(default=False)
is_cover_uploaded = models.BooleanField(default=False)
class Meta:
managed = False
db_table = 'bst_user_profile'
app_label = 'bst'
From my serializers.py:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','username',)
class BstUserActionLogSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = BstUserActionLog
fields = ('id', 'user', 'bst_action_type', 'action_date', 'bst_book', 'new_value_id', 'old_value_id')
depth = 3
The key to my solution is SerializerMethodField. With this a new field can be added which is calculated with a method. This method signature contains the object to be serialized. After that a regular method serializer is used to return the serialized object.
From my serializers.py
class BstUserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = BstUserProfile
fields = ('is_avatar_uploaded', 'is_cover_uploaded')
class BstUserActionLogSerializer(serializers.ModelSerializer):
user = UserSerializer()
user_profile = serializers.SerializerMethodField()
def get_user_profile(self, obj):
try:
user_profile = BstUserProfile.objects.get(user_id=obj.user_id)
return BstUserProfileSerializer(user_profile).data
except Exception as e:
return {}
class Meta:
model = BstUserActionLog
fields = ('id', 'user', 'user_profile', 'bst_action_type', 'action_date', 'bst_book', 'new_value_id', 'old_value_id')
depth = 3