Serializing specific fields from another model - django

I was trying to serialize policy_length, coverage_amount from Policy model and use it in a serializer that was using Insuree model.
I'm using Policy and Insuree models:
Policy model
class Policy(TimeStampedModel):
policy_length = models.FloatField(max_length=2, blank=True, null=True)
coverage_amount = models.FloatField(max_length=256, blank=True, null=True)
Insuree model
class Insuree(TimeStampedModel):
user = models.OneToOneField(
'User', related_name='insuree', null=False, on_delete=models.CASCADE,
primary_key=True)
coverage_amount = models.ForeignKey(Policy, on_delete=models.CASCADE, max_length=256, blank=True, null=True)
policy_length = models.ForeignKey(Policy, on_delete=models.CASCADE, max_length=2, blank=True, null=True)
class PolicySelectionSerializer(serializers.ModelSerializer):
class Meta:
model = Insuree
fields = ('age', 'gender', 'disposable_income') #Current fields
fields = ('age','gender',disposable_income', 'policy_length', 'coverage_amount') #The field I need and want to do

You may use Nested Serializer.
PolicySerializer(ModelSerializer)
class Meta:
model = Policy
fields = ( 'policy_length', 'coverage_amount')
InsureeSerializer(ModelSerializer)
class Meta:
policy = PolicySerializer(many = True)
model = Insuree
fields = ('age', 'gender', 'disposable_income', 'policy',)

Related

How to inner join multi tables or merge multi serializers in Django?

i have this code here for the models:
class Users(models.Model):
first_name = models.CharField(max_length=32, blank=True, null=True)
last_name = models.CharField(max_length=32, blank=True, null=True)
email = models.EmailField(max_length=254, unique=True)
class Images(models.Model):
user= models.ForeignKey(Users, on_delete=models.RESTRICT)
encoded_pic = models.JSONField(
encoder=None, default=dict, blank=True, null=True)
pic_thumbnail_path = models.CharField(max_length=222, blank=True, null=True)
class WorkingDays(models.Model):
user= models.ForeignKey(Users, on_delete=models.RESTRICT)
day = models.DateField(blank=True, null=True)
enter_time = models.DateTimeField(blank=True, null=True)
exit_time = models.CharField(max_length=32, blank=True, null=True)
class Departments(models.Model):
user= models.ForeignKey(Users, on_delete=models.RESTRICT)
department_name = models.CharField(max_length=32, blank=True, null=True)
These are the serializers:
class UserssSerializer(serializers.ModelSerializer):
class Meta:
model = Users
fields = '__all__'
class ImagesSerializer(serializers.ModelSerializer):
class Meta:
model = Images
fields = '__all__'
class WorkingDaysSerializer(serializers.ModelSerializer):
class Meta:
model = WorkingDays
fields = '__all__'
class DepartmentsSerializer(serializers.ModelSerializer):
class Meta:
model = WorkingDays
fields = '__all__'
I tried this code but it only returns the images fields not the others
data=Images.objects.filter(user_id__workingdays=pk).values()
What i want to do is to inner join images, workingdays and departments table using user_id field
also is there away to merge serializers of all these 3 tables to make the serializer returns all the fields from all the 3 tables?

How to allow blank field on OneToOne serializer field for Django REST Framework API?

When POSTing to my API endpoint I get a field is required error on a OneToOne field, but I create the OneToOne Field in the save() method of the model I'm POSTing.
I've tried setting default=None, null=True, and blank=True
Device Model
class Device(models.Model):
name = models.CharField(max_length=50)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
brand = models.TextField(max_length=50)
year_purchased = models.IntegerField()
serial_number = models.TextField(max_length=100)
info = models.TextField(max_length=100)
qrcode = models.ImageField(upload_to='', blank=True, null=True)
def save(self, **kwargs):
super(Device, self).save(**kwargs)
if not self.qrcode:
self.generate_qrcode()
if not self.checkouts.exists():
checkout = Checkout(item=self)
checkout.save()
Checkout Model
class Checkout(models.Model):
status_choices = (...)
# Fields
slug = extension_fields.AutoSlugField(populate_from='item', blank=True)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
due_back = models.DateField(null=True, blank=True)
checked_out = models.DateTimeField(blank=True, null=True)
status = models.CharField(max_length=2, choices=status_choices, default=in_stock)
# Relationship Fields
user = models.OneToOneField(
DeviceUser,
on_delete=models.CASCADE,
related_name="checkouts",
blank=True,
null=True,
default=None,
)
item = models.OneToOneField(
Device,
on_delete=models.CASCADE,
related_name="checkouts",
primary_key=True,
blank=True,
default=None,
)
Device Serializer
class DeviceSerializer(serializers.ModelSerializer):
class Meta:
model = models.Device
fields = (
'pk',
'name',
'created',
'last_updated',
'brand',
'year_purchased',
'serial_number',
'info',
'checkouts',
)
When POSTing http POST http://localhost:8000/main/api/device/ brand=test2 info=123213123 name=test2 serial_number=12321321 year_purchased=12 'Authorization: Token .....'
I expect to get a confirmation that a device was created, instead I get
"checkouts": [ "This field is required." ]
Specify checkouts field to your DeviceSerializer serializer as,
checkouts = serializers.DateTimeField(default=None, source='checkouts.checked_out', read_only=True)
# code sample
class DeviceSerializer(serializers.ModelSerializer):
checkouts = serializers.DateTimeField(default=None, source='checkouts.checked_out', read_only=True)
class Meta:
model = models.Device
fields = (
'pk',
'name',
'created',
'last_updated',
'brand',
'year_purchased',
'serial_number',
'info',
'checkouts',
)

django select only specific fields from many to many field in serializer

My models:
class RequisiteItem(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
enrollable = models.ForeignKey(Enrollable, on_delete=models.CASCADE)
created_by = models.ForeignKey(ElsUser, on_delete=models.CASCADE)
completed_within_days = models.IntegerField()
date_completed_by = models.DateTimeField(default=now, editable=False)
class Requisite(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(default=None, blank=True, null=True, max_length=255)
description = models.CharField(default=None, blank=True, null=True, max_length=255)
items = models.ManyToManyField(RequisiteItem, blank=True)
enrolments = models.ManyToManyField(Enrollee, blank=True)
created_by = models.ForeignKey(ElsUser, on_delete=models.CASCADE, related_name="requisites", default=None)
timestamp = models.DateTimeField(default=now, editable=False)
#property
def created_by_user(self):
return self.created_by.username
Serializer class:
class RequisiteSerializer(serializers.ModelSerializer):
created_by = serializers.CharField(source='created_by_user')
class Meta:
model = Requisite
fields = ('id', 'name', 'description', 'items', 'enrolments', 'created_by', 'timestamp')
read_only_fields = ['id']
depth = 1
I have enrolments ,created by,requisite items which are foreign keys and manytomany fields etc .In my list API i want only specific fileds from the foreign key to be displayed. For example in the created by field, Elsuser is a custom user inheriting from AbstractUser . I want only the username and email fields from this model and not the entire fields. Similar case for the manyto many fields . How do i implement this?
You can create a serializer to get only the required fields. Example:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('') #the fields you require to display
Then change your serializer as:
class RequisiteSerializer(serializers.ModelSerializer):
created_by = UserSerializer()
class Meta:
model = Requisite
fields = ('id', 'name', 'description', 'items', 'enrolments', 'created_by', 'timestamp')
read_only_fields = ['id']
depth = 1

Django rest nested serializer not displaying fields

I have a model Workflow and WorkflowLevel. Each workflow has many WOrkflow levels .Im trying to use nested serializer :
class WorkflowLevelSerializer
(serializers.ModelSerializer):
class Meta:
model = WorkflowLevel
fields = '__all__'
class
WorkflowSerializer
(serializers.ModelSerializer):
levels = WorkflowLevelSerializer(many=True)
class Meta:
model = Workflow
fields = ('id', 'name', 'description',
'tenant', 'levels')
models.py:
class Workflow(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=32, default=None, null=True)
description = models.CharField(max_length=100, default=None, null=True)
tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE, default=None,
null=False)
class Meta:
unique_together = ('name', 'tenant',)
class WorkflowLevel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE,
default=None, null=False)
level = models.IntegerField(default=None, null=False)
operation = models.CharField(max_length=32, default=None, null=False)
class Meta:
unique_together = ('workflow', 'level',)
The levels field is not displaying in the workflow listAPI view .
Getting error:
Got AttributeError when attempting to get a value
for field `levels` on serializer
`WorkflowSerializer`.
The serializer field might be named incorrectly
and not match any attribute or key on the
`Workflow` instance.
Original exception text was: 'Workflow' object
has no attribute 'levels'.
You can define related_name in the Model like this:
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, related_name="levels", default=None, null=False)
I am using related_name='levels', so that in Serializer, it will use that reverse relationship name to fetch WorkflowLevel data from db.

access to another model fields with foreign key in django admin

I have a contact us class in django model,that using "user_id" foreign key,in admin.py file,i want using userprofile data with user_id key,such as "name" filed,in userprofile model "user_id" is foreign_key too,how can do it?
in models.py :
class Ticket(models.Model):
user_id = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, editable=False, verbose_name="user")
replier_id = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name="replier")
guest_name = models.CharField(max_length=50, blank=True, null=True, editable=False)
guest_email = models.CharField(max_length=255, blank=True, null=True, editable=False)
user_phone = models.CharField(max_length=13, blank=True, null=True, editable=False)
subject = models.CharField(max_length=255, blank=True, null=True, editable=False)
message = models.TextField(editable=False)
reply = models.TextField(blank=True, null=True)
date = models.DateTimeField(auto_now=True, editable=False)
reply_date = models.DateTimeField(blank=True, null=True)
user_ip = models.GenericIPAddressField(editable=False)
in admin.py
class ContactUsAdmin(admin.ModelAdmin):
actions = None
fields = ('user_name', 'user_email', 'subject', 'date', 'message', 'user_phone', 'reply')
list_display = ('user_name', 'user_email', 'subject', 'date', 'is_replied')
list_filter = ('date',)
search_fields = ['user_id__first_name', 'user_id__email', 'guest_name', 'guest_email', 'subject', 'message']
readonly_fields = ('user_name', 'user_email', 'subject', 'date', 'message', 'user_phone', 'reply_date')
i want show name from UserProfile class in admin.py fields
By the question title of your query. I am giving an incentive how to do that in django:
class Album(models.Model):
AlbumName = models.CharField(max_length=250)
AlbumSinger = models.CharField(max_length=250)
AlbumGenre = models.CharField(max_length=250)
AlbumImage = models.FileField(null=True)
SingerImage = models.FileField(null=True)
class Musics(models.Model):
album = models.ForeignKey(Album, related_name='music')
MusicName = models.CharField(max_length=250)
MusicLength = models.CharField(max_length=250)
MusicFile = models.FileField(null=True)
Using foreignkey album in Musics. you can access to all the music according to their album. And to access them in admin, just import class name and do the following:
admin.site.register(Album)
admin.site.register(Musics)
I hope it will clear your confusion.
finally i resolve it,when in userprofile model,user_id has "profile" related_name,in every where,with user_id foreign key we have all related field from every model that user_id is foreign key in it
you can see those with using dir("you user_id instance").
so,with user_id.profile.name i get the profile name of user,without any importing or change!