How to get a value from SubFactory Django Unit Test - django-rest-framework

I have three classes.In OrdFactory i wana pass only id to "sku" field and sku is integer field.
class CoFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Co
name = factory.Sequence(lambda n: 'Co {}'.format(n))
class CrFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Cr
name = factory.Sequence(lambda n: 'Cr {}'.format(n))
class OrdFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Ord
sku = random.choice([factory.SubFactory(CrFactory), factory.SubFactory(CoFactory)])
quantity = 75.6
I am getting following error.
int() argument must be a string, a bytes-like object or a number, not 'Co'.
I have tried using id also:-
sku = random.choice([factory.SubFactory(CrFactory).id, factory.SubFactory(CoFactory).id])
but this also throwing error.

I have fixed using trait.Overload is also a alternative solution.
https://factoryboy.readthedocs.io/en/latest/reference.html#factory.Trait

Related

How to order the id in serializers in Django Rest Framework?

when I try to sort my id in my serializers it gives me an error : AttributeError: 'int' object has no attribute 'all'.
Here is the code of my serializers :
class DatasetPidTrierSerializer(serializers.HyperlinkedModelSerializer):
id = serializers.SerializerMethodField()
class Meta:
model = Dataset
fields = ['id']
def get_id(self, instance):
songs = instance.id.all().order_by('id')
return DatasetPidSerializer(songs, many=True).data
Here is the beginning of it : model Dataset
thank you for your help
First, you don't need to set id field in Dataset model. Django will do that automatically for you. You can define just two fields pid and iddatta_resolution.
class Dataset(models.Model):
pid = models.ManyToManyField(
...
)
iddata_resolution = models.ForeignKey(
...
)
And then in the serializer, you don't need to define id field. Because the default order will be id field automatically by Django.
class DatasetPidTrierSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Dataset
fields = ['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 ?

How to limit the number of objects given from nested serialization

Store has a foreign key to SimilarStore. Normally, there is about a hundred of similar stores in similarstore_set. Is there a way to limit the number of similar stores in similarstore_set when I make API with Django REST Framework?
serializer.py
class SimilarStoreSerializer(ModelSerializer):
class Meta:
model = SimilarStore
fields = ('domain', )
class StoreSerializer(ModelSerializer):
similarstore_set = SimilarStoreSerializer(many=True)
class Meta:
model = Store
fields = '__all__'
UPDATE
The following codes throws 'Store' object has no attribute 'similarstores_set', it actually has similarstore_set, why is it throwing the error?
class StoreSerializer(ModelSerializer):
image_set = ImageSerializer(many=True)
promotion_set = PromotionSerializer(many=True)
similar_stores = SerializerMethodField()
def get_similar_stores(self, obj):
# get 10 similar stores for this store
stores = obj.similarstores_set.all()[:10] <-- This line throws the error
return SimilarStoreSerializer(stores, many=True).data
class Meta:
model = Store
fields = '__all__'
You can use a SerializerMethodField to perform a custom lookup and limit the number of records:
class StoreSerializer(ModelSerializer):
similar_stores = serializers.SerializerMethodField()
def get_similar_stores(self, obj):
stores = obj.similarstore_set.all()[:10] # get 10 similar stores for this store
return SimilarStoreSerializer(stores, many=True).data
class Meta:
model = Store
fields = '__all__'
You could add a serializers.SerializerMethodField() for similarstore_set and define a method that would query the SimilarStore data and set similarstore_set. You could pass the number of elements you want in similarstore_set by passing context to your serializer. see https://www.django-rest-framework.org/api-guide/serializers/#including-extra-context

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.

Resources