How to filter results in nested relationships in django serializer? - django-rest-framework

I am following following tutorial
https://www.django-rest-framework.org/api-guide/relations/#nested-relationships
Here is my code.
class EmpSerializer(serializers.ModelSerializer):
pass
class Meta:
model = Employee
fields = ['name', 'dept', 'start_date', 'is_full_time']
class DeptCurrEmpSerializer(serializers.ModelSerializer):
pass
currEmployees = EmpSerializer(many=True, \
queryset=Employee.objects.filter(is_full_time=True))
class Meta:
model = Department
fields = ['id']
I want to limit the DeptCurrEmpSerializer to limit the results to only the full_time employees. I get an error "unexpected keyword argument 'queryset'". Is there any other way I can do this. Eventually, the EmpSerializer itself will have an "ActiveTasks" serializer under it.

Related

How to use same serializer for different request?

Suppose I have a VehicleSerializer
class VehicleSerializer(serializers.Serializer):
person = PersonSerializer()
class Meta:
model = Vehicle
fields = ('id', 'type', 'person')
I need to use this serializer for get as well as post api. For get request this should be same, but for post request, i need to send data like:
{
"type": "Car",
"person": 1 (the id of the person row)
}
How can i use same Vehicle Serializer to validate this request too? As the above serializer will take only the dict value for person key.
Any help will be appreciated.
I think you need to set the person_id field for writing.
class VehicleSerializer(serializers.ModelSerializer):
person = PersonSerializer(read_only = True)
person_id = serializers.IntegerField(write_only = True)
class Meta:
model = Vehicle
fields = ('id', 'type', 'person', 'person_id')

When DRF's field is named "products" it's returned as None

class OrderProductCreateSerializer(serializers.ModelSerializer):
class Meta:
model = OrderProduct
fields = ('product',)
class OrderProductCreateSerializer(serializers.ModelSerializer):
class Meta:
model = OrderProduct
fields = ('product',)
class OrderCreateSerializer(serializers.Serializer):
products = OrderProductCreateSerializer(many=True, required=True)
When field is named products I get None as result. When field is named as any other string (products1) I get valid results.
There is no special processing involved anywhere in code base related to products, just a simple many=True field.

Atrribute from nested relations is not read in serializer

I'm now using DRF as a backend of my project.
i have product model like this
class product(models.Model):
product_name = models.CharField(max_length=160)
i have category model like this
class category(models.Model):
category_name = models.CharField(max_length=60)
category_icon = models.ImageField(upload_to='category)
because 1 product can have multiple category and a lot of image I create
class product_category(models.Model):
product = models.ForeignKey(product, on_delete=models.CASCADE, related_name='product_collections')
category = models.ForeignKey(category, on_delete=models.CASCADE, related_name='category_collections')
and the last model
class product_image(models.Model):
product = models.ForeignKey(product, on_delete=models.CASCADE,related_name='image_collections')
product_img = models.ImageField(upload_to='product')
Now I have Serializer like this
class ProductCategorySerializer(serializers.ModelSerializer):
category_name = serializers.CharField(source='category.category_name')
class Meta:
model = product_category
fields = ('product_id','category_id','category_name')
class ProductImageSerializer(serializers.ModelSerializer):
class Meta:
model = product_images
fields = ('product_img',)
class ProductSerializer(serializers.ModelSerializer):
category_collections = CategoryProductSerializers(many=True)
image_collections = ProductImageSerializer(many=True)
class Meta:
model = product
fields = ('id','product_name','image_collections','category_collections')
From that serializer DRF will return
Error like this
Got AttributeError when attempting to get a value for field category_collections on serializer ProductSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the product instance.
but if i remove that category_collections field like this
class ProductSerializer(serializers.ModelSerializer):
# category_collections = CategoryProductSerializers(many=True)
image_collections = ProductImageSerializer(many=True)
class Meta:
model = product
fields = ('id','product_name','image_collections')
Everything is going fine, whats wrong with that categories collection, is my eye not seeing the mistake ?

Django DRF serializer - inserting data containing foreign key relationships

I have the following models:
class Contact(models.Model):
class Meta:
managed = False
db_table = 'contact'
class ContactPhone(models.Model):
contact = models.ForeignKey(Contact, on_delete = models.CASCADE)
number = models.CharField(max_length = 45)
class Meta:
managed = False
db_table = 'contact_phone'
Also, I have the following serializers:
class ContactSerializer(serializers.ModelSerializer):
server_id = serializers.IntegerField(source='id', read_only=True)
class Meta:
model = Contact
fields = '__all__'
class ContactPhoneSerializer(serializers.ModelSerializer):
class Meta:
model = ContactPhone
fields = '__all__'
Now, I have a view that insert phone numbers for an existing contact.
The input is a json that looks like this:
data = {'contact_id': 12322,
'phones':[{'number': '89120000001'}]}
The view:
def insert_contact_phone(request):
for record in request.data['phones']:
data['contact_id'] = request.data['contact_id']
serializer = ContactPhoneSerializer(data = data)
if serializer.is_valid():
serializer.save()
I end up with the following error:
RelatedObjectDoesNotExist at /contacts/edit ContactPhone has no
contact.
What am I doing wrong?
If you specify __all__ for the fields in your ContactPhoneSerializer, it does not include contact_id.
So the contact_id taken from the json input is not serialized. It is basically ignored and when you try to save and create new ContactPhone - it fails, because it does not have contact's foreign key correctly set.
But simply adding contact_id to the serializer's fields won't solve your problem.
In your view, i recommend you to set the contact instead:
data['contact'] = request.data['contact_id']
and pass this to the ContactPhoneSerializer.

Django admin form extra field

I want to add an extra field (column) that is not in the model. So, I created a model form in which the new extra field is defined.
admin.py
class WorkingHourForm(forms.ModelForm):
extra_field = forms.CharField(max_length=100)
class Meta:
model = WorkingHour
fields = ['day', 'period', 'time_range', 'extra_field']
class WorkingHourInline(admin.TabularInline):
model = WorkingHour
form = WorkingHourForm
This should work because it's pretty much a copy of an example in the documentation.
However, this raises the error: Unable to lookup 'extra_field' on WorkingHour or WorkingHourInline
What did I do wrong?
class WorkingHourForm(forms.ModelForm):
extra_field = forms.CharField(label='extra_field', max_length=100)
class Meta:
model = WorkingHour
fields = ['day', 'period', 'time_range', 'extra_field']
class WorkingHourInline(admin.TabularInline):
model = WorkingHour
form = WorkingHourForm
Adding label='extra_field' solved this for me in a similar use of tabularinline.. I think the django admin example works as is but when used in conjunction with the admin.TabularInline, it does not. Hope that helps.
remove extra_field from fields = ['day', 'period', 'time_range', 'extra_field']. If you do like that django will tries to get value for the extra_field from model. so, it will raises an error.
After modification, Above code will look like
class WorkingHourForm(forms.ModelForm):
extra_field = forms.CharField(max_length=100)
class Meta:
model = WorkingHour
fields = ['day', 'period', 'time_range']
class WorkingHourInline(admin.TabularInline):
model = WorkingHour
form = WorkingHourForm
Try adding this in your form's Meta:
labels = {"extra_field": "blah"}

Resources