I have a model where I didn't specify a primary key and Django generated one for me. Now I create a ModelForm for the model and I have specified id in the fields section of ModelForm. However, in my ModelForm object, the id field is not present.
Are only the model fields explicitly declared visible in the ModelForm?
Are only the model fields explicitly declared visible in the
ModelForm?
Yes, generally you don't want to mess with this field, if the user inputs a value for the id field it's very likely to be duplicated so this is something you want django to take care of for you.
Related
For establishing many-to-many relationships, django admin has a nice widget called 'filter_horizontal'.
The problem is - it only displays primary key of the related table.
How do I add other fields from the related table?
For example, if I have a many-to-many relationship in my Order model with User model, in 'Order' django admin I can only see User's primary key(id). How do I add their name into the widget?
Turns out it is changed in str method for the User model
As we can validate the values using the conventional model field then why Django REST Framework contains its own serializer fields. I know that serializer fields are used to handle the converting between primitive values and internal datatypes. Except this, is there anything different between them.
Well there is a ModelSerializer that can automatically provide the serializer fields based on your model fields (given the duality you described). A ModelSerializer allows you to select which models fields are going to appear as fields in the serializer, thus allowing you to show/hide some fields.
A field in a model, is conventionally tied to a data store (say a column in a database).
A DRF Serializer can exist without a Django model too, as it serves to communicate between the API and the client, and its fields can be in many forms that are independent from the model and the backing database, e.g. ReadOnlyField, SerializerMethodField etc
Model fields are what you keep in your database.
(it answers how you want your data organized)
Serializer fields are what you expose to your clients.
(it answers how you want your data represented)
For models.ForeignKey(User) of your model,
you can represent it in your serializer as an Int field, or UserSerializer(which you will define), or as http link that points to the api endpoint for the user.
You can represent the user with username, it's up to how you want to represent it.
With DRF,
You can hide model fields, mark it as read-only/write-only.
You can also add a field that is not mappable to a model field.
Both of them refers to the same thing with a little bit difference.
Model fields are used within the database i.e while creating the schema, visible to the developer only.
while Serializer fields are used to when exposing the api to the client, visible to client also.
I have the following serializer:
class ReqSerializer(serializers.ModelSerializer):
class Meta:
model = Earth
fields = ('area', )
and this model:
class Earth(models.Model):
area = models.IntegerField(default=0)
According to django-rest-framework Serializer fields the "required" option is
set to True by default which means if I try to validate the serializer without "area" field in the input,
I should get This field is required error. But is_valid() is passed and the model gets created with default area=0. However, Using this:
extra_kwargs = {
area': {'required': True},
}
Would solve the issue but why? What could change this behavior? Why the default "required=True"
has no effect?
Update:
I just noticed that if I remove the default=0 from the model, it will work as expected. Now the question is why setting default on model field cancels the required=True on serializer.
I believe your problem here is that the field is being automatically generated by Django REST framework, while the docs are coming from the perspective of you manually creating the field on the serializer.
According to django-rest-framework Serializer fields the "required" option is set to True by default
This is correct for fields that you specify on your own on the serializer. In the case of automatically generated fields, Django REST framework tries to determine the serializer field options that best match the model field, similar to how the Django forms does it for form fields. For serializer fields, this is largely undocumented at the moment so there is nothing that I can point you to.
But is_valid() is passed and the model gets created with default area=0.
This is because Django REST framework determines that the field has a default value, at which point is knows input is not strictly required because the model field will automatically give a default value in the event that the user passes nothing in. Of course, if you pass something into the serializer on creation, the value will be used instead of the default, which is what you would expect if you were manually creating the model.
Would solve the issue but why? What could change this behavior? Why the default "required=True" has no effect?
This will fix your issue because it is manually overriding the required=False that is set on the automatically generated serializer field. In Django REST framework 3.0, you can confirm that by calling repr(ReqSerializer()) and looking at the the automatically generated field.
I just noticed that if I remove the default=0 from the model, it will work as expected.
This is because Django REST framework no longer determines the default and adds the required=True to the serializer, like you were expecting.
I have a model which has a ForeignKey field, and I wish to change its value in a model instance, I tried something like this:
#object and user are model instances, owner is a FK field
object.owner = user
This raises a ValueError : "object.owner is not an instance of User"
Is there a workaround for this?
user should be a correct instance of User, and if you just created it instead of retrieved it from the database, it should be save()-d before you save object.
Make sure that user is an instance of the same User that was used in defining the ForeignKey.
I'm developing a system based on Django admin. So all models could be edited also only from admin site. Model has a char field 'user'. I want to set current logged in admin username (or firstname, or lastname) as default value to 'user' field. How could I implement this?
Default values are set as parameters when defining model fields, so I guess no request object could be recieved? Maybe I should set the value when creating instance of model (inside init method), but how I could achieve this?
I found this recipe helpful: http://code.djangoproject.com/wiki/CookBookNewformsAdminAndUser
This is how you do it on the form level and not the save http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield%5Ffor%5Fforeignkey