Django REST framework - sumbit only fields? - django

I use a model serializer in my code and need to get extra field value in the PUT request. This is to identify the user intention on certain operations. I see there are read_only and write_only option in serialize fields. But I can't use those since I'm not going to store this additional field to the model (it don't have such field).
How can I achieve this in the serializer correct way?
djangorestframework version 3.13.1

Found the solution based on the #loki's comment.
Included the serializer field as follows since I use it for PUT method only.
delete_now = serializers.BooleanField(default=False, write_only=True)

Related

When and where is `Field.blank` checked by DRF?

I have a model
class SomeModel(models.Model):
emails = ArrayField(models.EmailField(), default=list)
And let's say I have the following Serializer of the model:
class SomeModelSerializer(serializers.ModelSerializer):
class Meta:
model = SomeModel
fields = ['emails']
The email field is not blank-able, i.e: It's required to set a value for it when submitting a Form of the model, or when making changes to its Admin page.
My understanding is that DRF relies as well on Django's internal machinery to validate whether emails is missing on the Serializer data or not. But the thing is that I can't find where (and when) this happens.
I've found that DRF is not calling the Model's clean() method anymore (link). But what baffles me is that changing the blank value on the field seems to have a direct impact on the Serializer. I have switched to blank=True, and then the Serializer would allow it to be saved without that field... Then I switched back to blank=False, and the Serializer would fail if emails is not present.
So do you have any idea of when and where DRF checks for a field's blank value?
Thanks!
As far as I know, it simply doesn't. Those are only used across forms and the django admin interface.
I always specify those things on the serializer level, by setting the appropiate arguments for my fields (doc), in this case it would be allow_blank.
I am building REST APIs with django, and the only case where the blank property on the model field catches me, is when fiddling around on the admin page.
However, there appears to be a package that could be of interest to you:
django-seriously.
I haven't used it, but it appears to call full_clean() on every save().
Of course, this has the disadvantage that you will probably loose DRFs nice error messages.

Is there any possibility to add fields inside the fields of a Model

Assume I have a model named MyModel and I have a Field Named field Now I want to add three more fields inside the prescription like one field_a , field_b and field_c .
Does Django Allow that in any way or we have to make another model for this purpose and then link with Foreign Key to MyModel?
Well I think it is an idea that could lead to some really hard to maintain code and should be well thought through.
That aside If you have a look at:
https://docs.wagtail.io/en/stable/topics/streamfield.html
It's a special field meant for cms applications that uses json in the field to model dynamic fields and validations for it.
Also if you run postgres this might help. https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/fields/#jsonfield

Django rest framework hyperlinkrelatedfield for one table using primary key

I have a table called 'users' and 'location'. Users table has a foreign key that relates to location table. I have a users serializer to get the JSON. What would I do to get the hyperlinks for the users table using its primary key?
In django rest framework documentation, I couldn't find a solution. I tried using hyperlinkrelatedfield. But still I couldn't achieve this. Can someone help me in finding the solution?
Using rest-framework HyperlinkedRelatedField does not work because it was never built to expose the URL of the object being requested. Mainly because since the client already has the url of the user, why send it back again? Nevertheless you can achieve this by doing something like this.
class UserSerializer(serializers.ModelSerializer):
user_url = serializers.SerializerMethodField()
class Meta:
model = User
def get_label_location(self, obj):
return HyperlinkedRelatedField(view_name='user-detail',
read_only=True) \
.get_url(obj, view_name='label-detail',
request=self.context['request'], format=None)
Take note on a few things,
view-name param to the HyperlinkedRelatedField should be based on your url configuration
read-only has to be true since otherwise you'll have to specify the queryset. But since we have the object needed to generate the url we can ignore that.
I've set format param to None but you might want to set it based on your settings.
You can read up about SerializerMethodField here.

How to ignore a non-null constraint and make my field readonly using DRF fields?

Basically, I have a FileField and, on creation, the other fields are populated by the data extracted from this file.
Some fields of my model have a non-null contraint (a value has to be extracted from the file for those fields).
I'm using a ModelSerializer and drf fields to add allow_null to the fields (null=False in my model) as I am aware of Order of Serializer Validation in Django REST Framework.
The problem is that I want them to be readonly (I just want a form with a file input, remember ?) and according to the drf documentation :
Read-only fields are included in the API output, but should not be included in the input during create or update operations.
Because of that I sometimes have to put random values in those fields just to pass the validation phase even if those fields will be populated by the correct values (extracted from the file) afterwards.
How can I ignore the non-null constraint from my model and make my fields readonly in my serializer (not changing my model) ?
I safely removed my default validation (validators = []) as, in this particular case, I had to write the whole validation process (export all the data from my FileField to fill the others).
This enabled my serializer to do its job, without raising validation error, through the save method where I added the exported data from my file in my non null fields.
def save(self, **kwargs):
...
self.validated_data['my-non-null-field'] = value
It's a question of design here: you are forcing the serializer to perform some of the controller's job. My recommendation would be that you will overwrite the view's create method and inside there you will build your business logic:
receive the file in the request; validate it's type and content
parse the file in a sequential (low memory footprint!) manner
extract your "other fields" data
at this stage you can call your serializer which have all his fields mapped to the model in the dB properly; delegate any validation to him, together with model creation/update;
This approach will enable you to still request only a POST from your clients while not breaking the "chain of responsibilities" and keep your serializer clean and simple.
Makes sense?

Django registration, signals and not required extra fields

I would like to know the best way to use Django registration with extra fields, and how to solve the problem with fields that I don't need to be shown, everytime I use Django registration with extra fields, I'm having problem with fields not required
regBackend.py
...
profile.hobbies = form.data['hobbies']
...
for example hobbies field is not required, but i get error if the user don't select nothing in this field, django say "MultiValueDictKeyError"
Any idea about how to use signals and don't need to worry about the not required fields?
Thank you
Use dict.get() to get the value for a key that may or may not be present.
profile.hobbies = form.data.get("hobbies")
In your form class, you could set the optional fields to required=False so that if it's not selected, Django won't kick up a fuss.