New to using DRF. Curious as to what approaches some of you have used regarding storing a List.... I tried to implement the newly added ListField but I was not able to get it working. I'm using MySql as the db. I figured there was a DRF-specific way of achieving this.
For example, say this is the expected output:
{
"somenames": ["james", "jim"],
"somekey": "username",
}
models.py
class StringListField(serializers.ListField):
child = serializers.CharField()
class SomeClass(models.Model):
somenames = StringListField,
somekey = models.CharField(max_length=140, default='username')
def publish(self):
self.save()
def __str__(self):
return self.somekey
serializers.py
class MentionSerializer(serializers.ModelSerializer):
class Meta:
model = Mention
fields = ('somekey', 'somenames')
One option I could implement is just storing the List as a seperate table then reflecting them in the table I need them to nest them in with Foreign Key
or ManyToManyField
. Thanks for any suggestion.
I use this
deep_link = serializers.ListSerializer(child=serializers.CharField())
it's basically a shortcut of yours. The problem with your code is that you are confusing Models with Serializers. The Model is the database representation of your data. The model does not specify serializers. The serializer is the serialized representation of your model coming from the DB, used mostly for data transfer.
class SomeClass(models.Model):
somenames = StringListField
somekey = models.CharField(max_length=140, default='username')
here, you are telling your model that your Django model's field "somenames" is of type serializers.ListSerializers. That is not what you want. If you want to link a model to a list of strings you need to create a ManyToMany relationship or whatever you need. Below an example
class Name(models.Model):
name = models.CharField(max_length=100)
class SomeClass(models.Model):
somekey = models.CharField(max_length=100)
somenames = models.ManyToManyField(Names)
Then in your serializers you will have
class NameSerializer(serializers.ModelSerializer):
name = serializers.CharField()
class SomeClassSerializer(serializers.ModelSerializer):
somenames = NameSerializer(many=True)
somekey = serializers.CharField()
class Meta:
model = SomeClass
Ok so after delving into the DRF documentation, along with the help of @xbirkettx answer, I was able to achieve the result I wanted:
in models.py
Create your models. I set a ForeignKey
relationship to the parent class (in this case the Mention
class)
class Mention(models.Model):
...
class Hashtag(models.Model):
mention = models.ForeignKey(Mention, related_name='hashtags')
tagname = models.CharField(max_length=100)
class Meta:
unique_together = ('mention', 'tagname')
def __unicode__(self):
return '%s' % (self.tagname)
in serializers.py
Create the serializers for the item in the List (Hashtag)
for read/write you need to define to_internal_value
method
class HashListingField(serializers.RelatedField):
def to_internal_value(self, data):
tagname = data
return {
'tagname': tagname
}
def to_representation(self, value):
return value.tagname
be sure to add the queryset
argument to the serializer for write access
class MentionSerializer(serializers.ModelSerializer):
hashtags = HashListingFieldSerializer(many=True, queryset=Hashtag.objects.all())
class Meta:
model = Mention
def create(self, validated_data):
tags_data = validated_data.pop('hashtags')
mention = Mention.objects.create(**validated_data)
for tags_data in tags_data:
Hashtag.objects.create(mention=mention, **tags_data)
return mention