I'm having a bit of trouble with implementing the serialization for my server. It is a host to demonstrate homomorphic encryption. Storage on the server consists of integers (really two integer tuples (X,q)), which are tied to a single set, sets are tied to sessions, sessions are tied to users... sets & sessions can both be posted. Posting a set includes the user_id, session_id and multiple integers in the request. Posting a set includes the user_id, session_id, then multiple sets in the request. Also, for a set the server generates an ID and sets that value for all integers in the set, and includes it in the response. Ideally, the user_id and session_id are going to be put in once in either type of request. So for a session post, each set does not have the user_id, session_id, but for a set post the set does have those values.
For get requests, similar idea... one instance of user_id, session_id, and this time set_id because it was created in the post. A user can request a set or session in the GET request as well.
I understand the basic idea of serialization, but I have trouble when nesting comes into play. I scoured the web and found a few articles/tutorials (ex, https://cheat.readthedocs.io/en/latest/django/drf_serializers.html ) and tried to string together some stuff, with no luck.
models.py, any reference to Token is the device token auth from Django rest_framework.
class Session(models.Model):
session_id = models.CharField(max_length=40,primary_key=True) # pk
user_id = models.ForeignKey(Token,on_delete=models.CASCADE) # foreign key from token
class Set(models.Model):
set_id = models.CharField(max_length=40,primary_key=True) # primary key, not null
session_id = models.ForeignKey(Session,on_delete=models.CASCADE)
class Integer(models.Model):
class Meta:
unique_together = (("set_id","index"),)
# Django/DRF offer no multi-field PK, so
# will use autogenerated PK, then utilize
# uniqueness
set_id = models.ForeignKey(Set,on_delete=models.CASCADE)
index = models.IntegerField(default=0)
X = models.IntegerField(default=0)
q = models.IntegerField(default=0)
def __str__(self):
return "%s[%d]" % (self.set_id,self.index)
serializers.py
class IntegerSerializer(serializers.ModelSerializer):
user_id = serializers.CharField(required=False,allow_blank=False)
session_id = serializers.CharField(required=False,allow_blank=False)
set_id = serializers.CharField(required=False,allow_blank=False) # max length needed?
index = serializers.IntegerField(required=False,min_value=0) # cap set size w/ max_value?
X = serializers.IntegerField(required=True)
q = serializers.IntegerField(required=True)
class Meta:
model = Integer
fields = '__all__'
class SetSerializer(serializers.ModelSerializer):
user_id = serializers.CharField(required=False,allow_blank=False)
session_id = serializers.CharField(required=False,allow_blank=False)
set_id = serializers.CharField(required=False,allow_blank=False)
integer = IntegerSerializer(many=True)
def create(self, validated_data):
str_index = list(self.validated_data.keys())[-1]
integer_data = self.validated_data[str_index]
if str_index == "user_id" or str_index == "session_id":
return super().create(validated_data)
integer_serializer = IntegerSerializer(data=integer_data)
integer_serializer.is_valid(raise_exception=True)
serializer.validated_data['user_id'] = validated_data['user_id']
serializer.validated_data['session_id'] = validated_data['session_id']
serializer.validated_data['set_id'] = validated_data['set_id']
serializer.validated_data['index'] = int(str_index)
integer_serializer.save()
validated_data[str_index] = integer_serializer.save()
instance = super().create(validated_data)
return instance
class Meta:
depth = 1
model = Set
fields = '__all__'
# exclusively for grabbing user_id and session_id
class SessionInfoSerializer()
user_id = serializers.CharField(required=True,allow_blank=False)
session_id = serializers.CharField(required=True,allow_blank=False)
class Meta:
model = Session
fields '__all__'
class SessionSerializer(serializers.ModelSerializer):
user_id = serializers.CharField(required=True,allow_blank=False)
session_id = serializers.CharField(required=True,allow_blank=False)
sets = SetSerializer(many=True)
class Meta:
depth = 2
model = Session
fields = '__all__'
Thank you for any help!
Currently in your models, session.user_id
will actually return a Token
object then the actual id will be in session.user_id_id
.
So in SessionSerializer
the user_id
field is actually returning a Token
object instead of string.
When you have a field django.db.models.ForeignKey
in a model, you actually have two properties that you can access in the model instance. So for instance you have this model:
class User(models.Model): profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
You have user.profile
and user.profile_id
. user.profile
will return a Profile
object while user.profile_id
will return the foreign key id that is stored in the database
SessionSerializer
, you have a sets
. You have to assign the related_name
of Set.session_id
: class Set(models.Model): session_id = models.ForeignKey(Session,on_delete=models.CASCADE, related_name="sets")
otherwise accessing the reverse one-to-many will be set to the default session.set_set
( <model_name>_set
).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.