How do I use Serializer for something like This
class Language(BaseModel):
name = models.CharField(null=False, blank=False, unique=True, max_length=150)
class Helper(BaseModel):
languages = models.ManyToManyField('Language', blank=True, through="HelperLanguage")
class HelperLanguage(BaseModel):
helper = models.ForeignKey('Helper', on_delete=models.CASCADE)
language = models.ForeignKey('Language', on_delete=models.CASCADE)
read = models.BooleanField()
write = models.BooleanField()
speak = models.BooleanField(default=True)
class LanguageSerializer(ModelSerializer):
class Meta:
model = Language
fields = ["id", "name"]
class HelperLanguageSerializer(ModelSerializer):
language = LanguageSerializer(read_only=True)
class Meta:
model = HelperLanguage
fields = ["id", "language", "read", "write", "speak"]
class HelperPublicSerializer(ModelSerializer):
languages = HelperLanguageSerializer(read_only=True, many=True)
class Meta:
model = Helper
fields = ['id', 'languages']
while using HelperPublicSerialiser for list view I am getting error
Got AttributeError when attempting to get a value for field read on serializer HelperLanguageSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the Language instance.
I do understand the problem but couldn't find any solution probably not using membership model right way.
Related
Good day SO.
I saw dozens of SO answer about this but it is not working for me. Please point me on the right direction.
With this model:
class Major(models.Model):
major_name = models.CharField(max_length=100, default='', null=False)
is_active = models.BooleanField(default=True, null=False)
def __str__(self):
return self.major_name
class Minor(models.Model):
major = models.ForeignKey("Major", on_delete=models.CASCADE)
minor_name = models.CharField(max_length=100, default='', null=False)
def __str__(self):
return self.minor_name
I should use this serializer to get the major name in my minor serializer:
class MinorSerializer(serializers.ModelSerializer):
major_name = serializers.CharField(source='major.major_name', read_only=True)
class Meta:
model = Minor
fields = ["id", "minor_name", "major_id", "major_name"]
But major_name is not displayed on my json response.
I also tried to Serialize Major first then call it on my minor:
class MajorSerializer(serializers.ModelSerializer):
class Meta:
model = Major
fields = ["id", "major_name"]
class MinorSerializer(serializers.ModelSerializer):
major_name = MajorSerializer()
class Meta:
model = Minor
fields = ["id", "minor_name", "major_id", "major_name"]
But I got this error message instead "Got KeyError when attempting to get a value for field major_name on serializer MinorSerializer. \nThe serializer field might be named incorrectly and not match any attribute or key on the dict instance.\nOriginal exception text was: 'major_name'."
Note. The same error message if I remove read_only = True on my first answer
Additional Note:
I Tried this, and it gives me the same error message above.
class MinorSerializer(serializers.ModelSerializer):
class Meta:
model = Minor
fields = "__all__"
Looking for solution of this problem I encountered some similar threads, but referring to older versions of Django/DRF and thus not working in my case.
There are these two models:
class CsdModel(models.Model):
model_id = models.CharField("Item ID", max_length=8, primary_key=True)
name = models.CharField("Item Name", max_length=40)
active = models.BooleanField(default=True)
def __str__(self):
return self.model_id
class CsdListing(models.Model):
model_id = models.ForeignKey(CsdModel, on_delete=models.CASCADE, default=0, related_name='m_id')
name = models.ForeignKey(CsdModel, on_delete=models.CASCADE, default=0, related_name='m_name')
(...)
EDIT: Serializers are defined this way:
class CsdModelSerializer(serializers.ModelSerializer):
model_id = serializers.RegexField(regex='^\w{2}\d{3}$', allow_blank=False)
name = serializers.CharField(min_length=6, max_length=50, allow_blank=False)
class Meta:
model = CsdModel
fields = '__all__'
class CsdListingSerializer(serializers.ModelSerializer):
session_id = serializers.RegexField(regex='^s\d{2}$', allow_blank=False)
def validate_session_id(self, value):
(...)
class Meta:
model = CsdListing
fields = '__all__'
What I'd like to see, is model_id and name from CsdModel displayed inside a form created based on CsdListing model. But instead, the ID is duplicated:
How should I rebuild the model(s) to have both ID and name displayed in the form?
You should have only one foreign key. But the listing serializer should then reference the model as a nested serializer.
class CsdListing(models.Model):
model = models.ForeignKey(CsdModel, on_delete=models.CASCADE, default=0, related_name='listing')
class CsdListingSerializer(serializers.ModelSerializer):
model = CsdModelSerializer()
session_id = serializers.RegexField(regex='^s\d{2}$', allow_blank=False)
I have the following model and I would like to add a custom field called choices which will be a list of choices.
class HPIQuestionBank(models.Model):
label = models.CharField(
max_length=200,
db_index=True,
blank=True,
null=True)
template = models.ForeignKey(
HPIFilter, blank=True, null=True, on_delete=models.CASCADE, default='')
I have implemented the following in the serializers.
class CheckBoxesListField(serializers.ListField):
child = serializers.CharField(allow_null = True, allow_blank=True)
class TemplateQuestionBankSerializer(serializers.ModelSerializer):
answer_type = serializers.CharField(allow_null = True, allow_blank=True)
checkboxes = CheckBoxesListField()
hpianswers_set =TemplateAnswerSerializer(many=True)
class Meta:
model = HPIQuestionBank
fields = ['id','label','hpianswers_set','answer_type','checkboxes']
I'm using the serializer on my GET method. When I attempt to make a request I get the following error:
AttributeError at /api/clinic2/history/template/6/
Got AttributeError when attempting to get a value for field `checkboxes` on serializer `TemplateQuestionBankSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `HPIQuestionBank` instance.
Original exception text was: 'HPIQuestionBank' object has no attribute 'checkboxes'.
If you need to read data only you can try:
class Meta:
model = HPIQuestionBank
fields = ['id','label','hpianswers_set','answer_type',]
read_only_fields = ['checkboxes',]
Or you can work with SerializerMethodField as
class TemplateQuestionBankSerializer(serializers.ModelSerializer):
answer_type = serializers.CharField(allow_null = True, allow_blank=True)
checkboxes = SerializerMethodField()
def get_checkboxes(self, instance):
return CheckBoxesListField(instance).data
I have the following models
class STUser(AbstractBaseUser):
email = models.EmailField(unique=True)
name = models.CharField(max_length=255)
companyname = models.CharField(max_length=200, blank=True, null=True)
...
class VenuePermissions(models.Model):
user = models.ForeignKey(STUser, on_delete=models.CASCADE)
venue = models.ForeignKey(Venue, on_delete=models.CASCADE)
signupvaildatestring = models.CharField(max_length=200, blank=True, null=True)
...
I want to grab all the STUser objects and grab all their permissions.
So what I would like is to grab all the VenuePermissions objects. And grab the user and venue object of each venuePermission
Two ways I can do this. use the VenuePermissions_set attribute on STUser but then how do I grab the venue when its just going to be a pk value?
Or focus on the VenuePermissions objects and grab the user and venue from the pk values but how?
I remember nested queries, and I kinda did one in my browse code.
here is an example:
rooms = Room.objects.filter(venue=OuterRef('pk'), sixtyroundseatingoption= True)
venuelist = venuelist.annotate(sixtyrounds=Exists(rooms))
venuelist = venuelist.filter(Q(sixtyrounds = True) | Q(fullbuyoutsixtyroundseatingoption = True))
I've done the set objects in a serializer before
Example serializer:
class RoomAndImageSerializer(serializers.ModelSerializer):
roomimage_set = RoomImageSerializer(many=True, read_only=True)
class Meta:
model = Room
fields = ('pk','name')
any help with this query would be appreciated!
So this is what I am currently trying, I will post an answer if this works:
class VenueUserList(ListAPIView):
serializer_class = VenueUserListSerializer
queryset = VenuePermissions.objects.select_related('user').select_related('venue').filter(signupvaildatestring=None)
class VenueUserListSerializer(serializers.ModelSerializer):
user = UserSerializer()
venue = VenueSerializer()
class Meta:
model = VenuePermissions
fields = ('user', 'venue', 'isvenueviewer', 'isvenueeventplanner', 'isvenueadministrator')
Here is the answer. However I still need to group venues by user. Working on that.
class VenueUserList(ListAPIView):
serializer_class = VenueUserListSerializer
queryset = VenuePermissions.objects.select_related('user').select_related('venue').filter(signupvaildatestring=None)
class VenueUserListSerializer(serializers.ModelSerializer):
user = UserSerializer()
venue = VenueSerializer()
class Meta:
model = VenuePermissions
fields = ('user', 'venue', 'isvenueviewer', 'isvenueeventplanner', 'isvenueadministrator')
I'm building a serializer in django using the django rest framework. I need to filter the query set for a nested model.
I found How do you filter a nested serializer in Django Rest Framework?, which seemed to have the answer, but when I implemented it there was no change in my data. The only difference I can see is that the serializer referencing the filtered list serializer has other fields as well.
The models (abbreviated for clarity):
class GCUser(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
is_member = models.BooleanField(default=False)
age = models.SmallIntegerField(blank=True, null=True)
session_key = models.CharField(max_length=100, db_index=True, blank=True, null=True)
class Connection(models.Model):
creation_date = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(GCUser, related_name='user_connection')
event = models.ForeignKey(Event, related_name='event_connection')
role = models.CharField(max_length=8, choices=constants.Roles.ROLE_CHOICES,)
class Event(Game):
creation_date = models.DateTimeField(auto_now_add=True)
public = models.BooleanField(default=False)
start_time = models.DateTimeField(null=True, blank=True)
end_time = models.DateTimeField(null=True, blank=True)
gm_is_player = models.BooleanField(default=False,
help_text='Check if GM will be playing the game',
verbose_name='GM is a player')
gm_is_designer = models.BooleanField(default=False, help_text='Check if GM designed the game')
user_notes = models.TextField(blank=True, default='', verbose_name='Note to Scheduler')
scheduler_notes = models.TextField(blank=True, default='')
experience = models.CharField(max_length=3, choices=constants.ExpLevels.EXPERIENCE_CHOICES,
default=constants.ExpLevels.NOVICE,)
status = models.CharField(max_length=4, db_index=True,
choices=constants.Status.STATUS_CHOICES,)
Here's my code:
class FilteredListSerializer(serializers.ListSerializer):
def to_representation(self, data):
data = data.filter(status=constants.Status.ASSIGNED).order_by('start_time')
return super(FilteredListSerializer, self).to_representation(data)
class UserEventSerializer(serializers.ModelSerializer):
class Meta:
list_serializer_class = FilteredListSerializer
model = models.Event
fields = ('id', 'event_name', 'conflict_type', 'start_time', 'end_time')
class UserConnectionSerializer(serializers.ModelSerializer):
event = UserEventSerializer()
class Meta:
model = models.Connection
fields = ('get_role_display', 'conflict_type', 'event')
class GCUserSerializer(serializers.ModelSerializer):
user_connection = UserConnectionSerializer(many=True)
class Meta:
model = models.GCUser
fields = ('pk', 'first_name', 'last_name', 'email',
'is_member', 'age', 'user_connection')
PyCharm tells me that "class FilteredListSerializer must implement all abstract methods" but it doesn't actually throw an error. I put a breakpoint at the first line of the list serializer, but it doesn't get tripped.
I'm using Python 3.4 with django 1.7.
Thanks in advance for your help.
Edited to add: Looking into the serializer code, I realized what may be the key difference: my call has many=True, whereas the one from the previous post didn't. I tried taking out the model=, but as expected that threw an error, so apparently the "working" code in the earlier post didn't actually run as written.
So I am not sure how to use the method you are using, but, if I understand your question correctly, I believe you could do something like this:
class UserEventSerializer(serializers.ModelSerializer):
class Meta:
model = models.Event
fields = ('id', 'event_name', 'conflict_type', 'start_time', 'end_time')
class UserConnectionSerializer(serializers.ModelSerializer):
event = serializers.SerializerMethodField()
class Meta:
model = models.Connection
fields = ('get_role_display', 'conflict_type', 'event')
def get_event(self, obj):
if obj.event.status == constants.Status.ASSIGNED:
serializer = UserEventSerializer(obj.event)
return serializer.data
else:
serializer = UserEventSerializer(None)
return serializer.data
N.B. This assumes that you are trying to exclude Events from being serialized if their status is not assigned.
I hope this helps. If I didn't understand the problem, let me know.
it's not a bug or error. ModelSerializer has got already implemented all needed methods (most inhereted from Serializer class), but ListSerializer inherits from BaseSerializer and got implemented e.g.: .create() or .to_representation(), but not .update(). I've got some similar problems in PyCharm, when subclassing a Serializer. After implementing create, update and to_representation methods this issue was gone