Is there any way to set my serializer fields as not required by default? it'll take me hours to set every field of every serializer I have as not required so I wanted to know if there's any shortcut.
One example:
class ComputersSerializer(serializers.ModelSerializer):
name = serializers.CharField(required=False)
serial = serializers.CharField(required=False)
otherserial = serializers.CharField(required=False)
contact = serializers.CharField(required=False)
contact_num = serializers.CharField(required=False)
comment = serializers.CharField(required=False)
date_mod = serializers.DateTimeField(required=False)
is_template = serializers.IntegerField(default=0)
template_name = serializers.CharField(required=False)
is_deleted = serializers.IntegerField(default=0)
is_dynamic = serializers.IntegerField(default=0)
ticket_tco = serializers.DecimalField(max_digits=20, decimal_places=4, required=False)
uuid = serializers.CharField(required=False)
date_creation = serializers.DateTimeField(required=False)
is_recursive = serializers.IntegerField(default=0)
last_inventory_update = serializers.DateTimeField(required=False)
computertypes = ComputertypesSerializer(required=False)
computermodels = ComputermodelsSerializer(required=False)
entities = EntitiesSerializer(required=False)
networks = NetworksSerializer(required=False)
locations = LocationsSerializer(required=False)
autoupdatesystems = AutoupdatesystemsSerializer(required=False)
users = assistanceSerializers.UsersSerializer(required=False)
groups = assistanceSerializers.GroupsSerializer(required=False)
states = StatesSerializer(required=False)
users_tech = assistanceSerializers.UsersSerializer(required=False)
groups_tech = assistanceSerializers.GroupsSerializer(required=False)
manufacturers = ManufacturersSerializer(required=False)
class Meta:
model = Computers
fields = '__all__'
For the moment I had to set it for each field. I've been searching if someone had the same problem but it looks like I'm lazier than the rest of programmers.
If you want to make the field optional, it should be defined in your model.
The ModelSerializer will react to that.
From the docs:
If you're using Model Serializer default value will be False if you have specified blank=True or default or null=True at your field in your Model.
Try this:
class ComputersSerializer(serializers.ModelSerializer):
class Meta:
model = Computers
fields = '__all__'
extra_kwargs = {field.name:{'required': False} for field in Computers._meta.get_fields()}
Related
i have model as follows:
class UserWorkspace(models.Model):
workspace = models.ForeignKey(
"Workspace", models.CASCADE, db_column="workspace_uuid"
)
user = models.ForeignKey("User", models.CASCADE, db_column="user_uuid")
and i need to change the name in serializer i tried:
class UserWorkspaceSerializer(serializers.ModelSerializer):
workspace_uuid = serializers.PrimaryKeyRelatedField(source="workspace", queryset=Workspace.objects.all())
user_uuid = serializers.PrimaryKeyRelatedField(source="user", queryset=User.objects.all())
class Meta:
model = UserWorkspace
fields = ("workspace_uuid", "user_uuid")
but i get the error
return self.fields[key]
KeyError: 'workspace'
change your code like this
workspace = serializers.PrimaryKeyRelatedField(source="workspace_uuid", queryset=Workspace.objects.all())
user = serializers.PrimaryKeyRelatedField(source="user_uuid", queryset=User.objects.all())
Source Documentation
I have the following models in Django that have a structure as follows:
class Office_Accounts(models.Model):
accountid = models.EmailField(max_length=200, unique=True)
validtill = models.DateField(default=datetime.now)
limit = models.CharField(max_length=2)
class Device(models.Model):
device_type = models.ForeignKey(DeviceType,to_field='device_type')
serial_number = models.CharField(max_length=200,unique=True)
in_use_by = models.ForeignKey(User,to_field='username')
brand = models.CharField(max_length=200,default="-", null=False)
model = models.CharField(max_length=200,default="-", null=False)
type_number = models.CharField(max_length=200,blank=True,null=True, default = None)
mac_address = models.CharField(max_length=200,blank=True,null=True, default = None)
invoice = models.FileField(upload_to='Device_Invoice', null=True, blank = True)
msofficeaccount = models.ForeignKey(Office_Accounts, to_field="accountid")
class Meta:
verbose_name_plural = "Devices"
def full_name(self):
return self.device_type + self.serial_number + self.brand
I will display both of the models in admin.py.
Now, I want to display the count of each accountid present in the field "msofficeaccount" (present in Device Models) in my admin page of Office_Accounts model. For an example if xyz#abc.com appears in 10 rows of msofficeaccount field then, the count should be displayed as 10 in Office_Accounts admin page. Can anyone please guide me how should I approach this problem to solve it?
You could add a method to your admin class that returns the count of related devices for each office_account, but that would be very inefficient. Instead you can override get_queryset to annotate the count from a database aggregation function:
from django.db.models import Count
class Office_AccountsAdmin(admin.ModelAdmin):
list_display = (..., 'device_count')
...
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.annotate(device_count=Count('device'))
(On a minor note, Python style is always to use CamelCase for class names, and Django style is to use singular model names, so your model should really be called OfficeAccount.)
I've encountered a huge problem with a single Many to many relationship, Im trying to send the id's of the users to the group serializer in order for me to save them and create the group however the id is never recorded and grupos is created with nothing but saves nombre and creates the object.
Models.py
class Usuarios(models.Model):
class Meta:
db_table = "Usuarios"
idUsuario = models.AutoField(primary_key=True)
tipoUsuario = models.BooleanField(blank=False)
nombre = models.CharField(max_length=100,blank=False)
idUser = models.IntegerField(blank=False)
idEscuela = models.ForeignKey(Escuelas, on_delete=models.CASCADE)
class Grupos(models.Model):
class Meta:
db_table = "Grupos"
idGrupo = models.AutoField(primary_key=True)
nombre = models.CharField(max_length=30,blank=False,unique=True)
idUsuario = models.ManyToManyField(Usuarios)
class idUsuarioSerializer(serializers.Serializer):
#idUsuario = serializers.IntegerField(required=True)
class Meta:
model = Usuarios
fields = ('idUsuario',)
class GrupoSerializer(serializers.Serializer):
nombre = serializers.CharField(required=True)
idUsuario = idUsuarioSerializer(many=True)
class Meta:
model = Grupos
fields = ('nombre','idUsuario')
def create(self, validated_data):
idUsuarios_data = validated_data.pop('idUsuario')
grupo = Grupos.objects.create(**validated_data)
for idUsuario_data in idUsuarios_data:
#print(**idUsuario_data)
#Usuarios.objects.create(grupo=grupo,**idUsuario_data)
grupo.idUsuario.add(**idUsuario_data)
grupo.save()
return grupo
However this saves nothing on idUsuario field and also if I do it like the documentation it gives me an error "group is not a valid keyword" or even if I use "idGrupo" it says the same, I already check other answers looks like it's not possible, already tried add method too.
I send the following json
{
"nombre": "4B",
"idUsuario":[{"id":1},{"id":2}]
}
Try something like this,
for idUsuario_data in idUsuarios_data:
grupo.idUsuario.add(idUsuario_data['id'])
grupo.save()
With my parent model - StudioProfile, other models have a foreign key relationship to StudioProfile. How can I get all related table data when an API request is made to my StudioProfile serializer. Below are my models, views and serializers,
class StudioProfile(models.Model):
name = models.CharField(max_length = 120)
address_1 = models.CharField(max_length = 200)
address_2 = models.CharField(max_length = 200)
class StudioServices(models.Model):
studio_profile = models.ForeignKey(StudioProfile, related_name = "services")
service_name = models.CharField(max_length = 50)
class StudioPicture(models.Model):
studio_profile = models.ForeignKey(StudioProfile, related_name = "pic_of_studio")
picture = models.ImageField(upload_to = 'img_gallery', null = True, blank = True)
Serializers.py
class StudioServicesSerializer(serializers.ModelSerializer):
class Meta:
model = StudioServices
fields = ('studio_profile', 'service_name')
class StudioPicSerializer(serializers.ModelSerializer):
class Meta:
model = StudioPicture
fields = ('picture')
class StudioProfileSerializer(serializers.ModelSerializer):
services = StudioServicesSerializer(source = "StudioServices")
pic_of_studio = StudioPicSerializer(source = "StudioPicture")
class Meta:
model = StudioProfile
fields = ( 'address_1', 'address_2','services','pic_of_studio' )
views.py
class StudioProfile(ListAPIView):
permission_classes = (ReadWithoutAuthentication,)
serializer_class = StudioProfileSerializer
queryset = StudioProfile.objects.select_related().filter(id = 1)
Am not able to get the data. What am I doing wrong here? When I do a request to StudioProfile class how can I get all the related entries.
Traceback:
Got AttributeError when attempting to get a value for field service_name on serializer StudioProfileSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the StudioProfile instance.
Original exception text was: 'StudioProfile' object has no attribute 'StudioServices'.
I think that you might need to include many=true and change the source to the be related_name in the StudioProfileSerializer:
class StudioProfileSerializer(serializers.ModelSerializer):
services = StudioServicesSerializer(many = true, source = "services")
pic_of_studio = StudioPicSerializer(many = true, source = "pic_of_studio")
class Meta:
model = StudioProfile
fields = ( 'address_1', 'address_2','services','pic_of_studio' )
I have two models:
class Organization(models.Model):
name = models.CharField(max_length=64)
class OrgUser(User):
organization = models.ForeignKey(Organization, related_name='users')
role = models.CharField(max_length=1, choices=USER_TYPE_CHOICES)
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = OrgUser
depth = 1
fields = ('email', 'role', 'organization',)
class OrganizationSerializer(serializers.HyperlinkedModelSerializer):
users = USerSerializer(many=True)
class Meta:
model = Organization
depth = 1
fields = ('name', 'users',)
I'm using the Django REST Framework and I'm trying to get the following output for the given URLS:
GET /organization/
{
'name':'Hello World',
'users':[{ 'email':'test#gmail.com', 'role':'A' }]
}
GET /user/
{
'email':'test#gmail.com',
'role':'A',
'organization':{ 'name':'Hello World' }
}
So what's happening is GET /organization/ is giving me the users array and the organization information again.
I've been racking my brain setting the depth property on my serializer, but I can't figure it out for the life of me. If someone could please point me in the right direction, I'd greatly appreciate it.
The problem is that you want different output from your UserSerializer depending on if it's being used alone (i.e. at GET /user/) or as a nested relation (i.e. at GET /organization/).
Assuming you want different fields in both, you could just create a third Serializer to use for the nested relationship that only includes the fields you want in the OrganizationSerializer. This may not be the most elegant way to do it, but I can't find any alternatives.
Sample code:
class Organization(models.Model):
name = models.CharField(max_length=64)
class OrgUser(User):
organization = models.ForeignKey(Organization, related_name='users')
role = models.CharField(max_length=1, choices=USER_TYPE_CHOICES)
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = OrgUser
depth = 1
fields = ('email', 'role', 'organization',)
class OrganizationUserSerializer(serializers.HyperlinkedModelSerializer): # New Serializer
class Meta:
model = OrgUser
depth = 1
fields = ('email', 'role',)
class OrganizationSerializer(serializers.HyperlinkedModelSerializer):
users = OrganizationUserSerializer(many=True) # Change to new serializer
class Meta:
model = Organization
depth = 1
fields = ('name', 'users',)