I have two models:
class Vehicle(Model):
name = models.CharField(max_length=50)
class Driver(Model):
vehicle = models.ForeignKey(Vehicle, related_name='owned_vehicle')
name = models.CharField(max_length=100)
now on my forms.py:
class MyForm(forms.Form):
drivers = Driver.objects.order_by('name')
drivers_list = forms.ModelChoiceField(drivers, empty_label='* Driver *', label='Driver')
The problem is drivers_list also includes the vehicles in the list.
How can I prevent this form from including the ForeignKey field into the ModelChoiceField?
Why are you not using model form for drivers,
class DriverForm(forms.ModelForm):
class Meta:
model = Article
fields = ['name', 'vehicle']
For your own forms,
class MyForm(forms.Form):
driver_list = forms.ModelChoiceField(queryset=Driver.objects.order_by('name'))
# then other attributes which you want to map with driver
Related
The requirement is "I want to insert person with the person groups selection and also at the time of Creating person group I can choose persons for that particular group".
I've added two models in my models.py and manage many to many relationship between.
models.py
from django.db import models
class PersonGroup(models.Model):
id = models.AutoField(primary_key=True)
groupName = models.CharField(max_length=30)
detail = models.CharField(max_length=200)
class Person(models.Model):
id = models.AutoField(primary_key=True)
personId = models.CharField(max_length=20)
personName = models.CharField(max_length=20)
state = models.IntegerField()
personGroup = models.ManyToManyField(PersonGroup, related_name="person_list", blank=True)
serializers.py
class PersonSerializer(serializers.ModelSerializer):
personGroup = serializers.PrimaryKeyRelatedField(queryset=PersonGroup.objects.all(), many=True)
class Meta:
model = Person
fields = '__all__'
class PersonGroupSerializer(serializers.ModelSerializer):
person_list = PersonSerializer(many=True, read_only=True)
class Meta:
model = PersonGroup
fields = '__all__'
The above code help me to create person with personGroup selection
But, I also want to add persons selection at the time of create personGroup. Currently at the time of creating personGroup I'm not allowed to enter persons.
Please let me know if there any solution by which I can also select available persons at the time of person group creation.
Your person_list field in the PersonGroupSerializer is on read only, so you can't modify it using the API.
person_list = serializers.PrimaryKeyRelatedField(queryset=Person.objects.all(), many=True)
Try removing this arg.
You might also want to switch to a ForeignKey field instead of slugged.
I have two models where employee have relation with person model but person have no relation with employee model.
Like:
class Person(models.Model):
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
class Employee(models.Model):
person = models.ForeignKey(Person, related_name='person_info')
code = models.CharField()
In such cases I want code field data in person serializer.
I can solved this with writing method in person model or using SerializerMethodField in person serializer
like this:
def get_employee_code(self):
return Employee.objects.get(person=self).id
and add this as source in person serializer
employee_code = serializers.CharField(source='get_employee_code')
Or adding employee serializer into person serialiszer
class PersonSerializer(serializers.ModelSerializer):
employee = EmployeeSerializer()
class Meta:
model = Person
fields = ('name', 'address', 'employee')
But i was trying to do this with reverse relation but i can't. I have tried like this, it gives an error
Serializer:
class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.CharField(source='person_info.code')
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')
How can i solve this with reverse relation?
At the moment because you are using a ForeignKey field on the person attribute, it means that its returning a list when you access the reverse relation.
One solution would be to use a slug related field, though this must have many and read_only set to True, and will return a list because of the ForeignKey field.
class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.SlugRelatedField(
source='person_info',
slug_field='code',
many=True,
read_only=True,
)
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')
The other option is to change your ForeignKey into a OneToOneField, which would still need read_only set to True but it will not return a list.
class Person(models.Model):
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
class Employee(models.Model):
person = models.OneToOneField(Person, related_name='person_info')
code = models.CharField()
class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.SlugRelatedField(
source='person_info',
slug_field='code',
read_only=True,
)
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')
Or, if you don't want to change the ForeignKey, you could add a employee_code property method to the model instead to return the first employee code in the person_info relation.
class Person(models.Model):
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
#property
def employee_code(self):
employees = self.person_info.filter()
if employees.exists():
return employees.first().code
return ''
class Employee(models.Model):
person = models.OneToOneField(Person, related_name='person_info')
code = models.CharField()
class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.CharField(
read_only=True,
)
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')
you can access the reverse relation with custom SerializerMethodField()
class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.SerializerMethodField()
def get_employee_code(self, obj):
return obj.person_info.code
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')
I have my code set up as follows:
models.py
class Category(models.Model):
name = models.CharField(max_length=255)
class Product(models.Model):
category = models.ForeignKey(Category)
forms.py
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ('category',)
widgets = {
#'category' : forms.TextInput(attrs={'placeholder' : 'Select the category'}),
}
Basically, right now, without the widgets part, I get -------- as the placeholder for this field. However, I want to get 'Select the category', how can I do this? Thanks!
You can set custom placeholder using empty_label field:
class ProductForm(forms.ModelForm):
category = forms.ModelChoiceField(queryset=Category.objects.all(), empty_label='Select the category')
class Meta:
model = Product
I use rest framework, I have field in user emloyee.company which is has field name. I need display only name string, but I have dict.
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ('name',)
class UserSerializer(MySerializer):
company = CompanySerializer(source='employee.company')
class Meta:
fields = (..., 'company')
I've got:
{...,"company":{"name":"My company"}}
I need:
{...,"company":"My company"}
Thanks for any help.
Change:
company = CompanySerializer(source='employee.company')
to:
company = serializers.ReadOnlyField(source='employee.company.name')
I have form which generates from model
class UserProfile(models.Model):
company = models.ForeignKey(Company)
user = models.OneToOneField(User)
department = models.CharField(max_length=100)
position = models.CharField(max_length=100)
class UserProfileForm(ModelForm):
company_id = ModelChoiceField(queryset=Company.objects.all(),
widget=HiddenInput())
class Meta:
model = UserProfile
exclude = ('user')
But it's doesn't work, and company_id is stay visible select field.
How I can create hidden field with company id ?
fieldnames between model and form should match. Use company in stead of company_id and it'll work.