I have this models
class Driver(models.Model):
first_name = models.CharField(max_length=250)
last_name = models.CharField(max_length=250)
created_at = models.DateTimeField(default=NOW)
updated_at = models.DateTimeField(default=NOW)
def __str__(self):
return self.first_name
class Vehicle(models.Model):
driver_id = models.ForeignKey(Driver,on_delete=SET_NULL,unique=True,null=True, blank=True)
make = models.CharField(max_length=150)
model = models.CharField(max_length=150)
plate_number = models.CharField(max_length=10,validators = [validate_plate_numberLATIN,validate_plate_numberCYRYLLIC], unique=True)
created_at = models.DateTimeField(default=NOW)
updated_at = models.DateTimeField(default=NOW)
def __str__(self):
return self.make
I try to set foreign key in my post request into Vehicle model
#method_decorator(csrf_exempt, name='dispatch')
def post(self,request,*args, **kwargs):
body = json.loads(request.body.decode("utf-8"))
newCar = Vehicle.objects.create(driver_id=body['driver_id'],make=body['make'],model=body['model'],plate_number=body['plate_number'])
data = json.loads(serializers.serialize('json',[newCar]))
return JsonResponse({'success':data})
And get this error
ValueError: Cannot assign "1": "Vehicle.driver_id" must be a "Driver" instance.
How to get rid off this error? How I can create an instance of Driver and 'post' an id?
You can do it in 2 ways
If you need the driver instance in somewhere in the code you can use this
driver_instance = Driver.objects.get(pk=body['driver_id'])
Vehicle.objects.create(driver_id=driver_instance,..)
Vehicle.objects.create(driver_id_id=body['driver_id'], ...)
The raw value of a ForeignKey can be accessed by appending "_id" to the field name, this can also be used to create an instance using the raw value
Vehicle.objects.create(driver_id_id=body['driver_id'], ...)
Related
I want to make the string representation of a field show data based on a JOIN, for instance:
For Penciler - I want the string representation to resolve to
John Doe (DC) - But the publisher value in that class is a Foreign Key - How do I reference the publisherName?
from django.db import models
class Series(models.Model):
seriesId = models.AutoField(primary_key=True)
series_name = models.CharField(max_length=300)
publisher = models.ForeignKey('Publisher', on_delete = models.PROTECT)
first_published = models.DateField()
last_published = models.DateField()
discontinued = models.BooleanField(default=False)
def __str__(self):
return f'{self.series_name} - {self.publisher} ({self.first_published - self.last_published})'
class Meta:
ordering = ['publication_year','title']
class Publisher(models.Model):
publisherId = models.AutoField(primary_key=True)
publisherName = models.CharField(max_length=250, null=False)
def __self__(self):
return self.publisherName
class Penciler(models.Model):
pencilerID = models.AutoField(primary_key=True)
pencilerName = models.CharField(max_length=200)
publisher = models.ForeignKey('Publisher', on_delete= models.PROTECT)
def __str__(self):
return self.pencilerName (self.publisher)
You can access the related Publisher instance through the ForeignKey field and get the publisherName in the __str__() method so:
def __str__(self):
publisher_name = self.publisher.publisherName
return f'{self.pencilerName} ({publisher_name})'
Additionally, I'd recommend you to use string formatting, such as using f-strings.
It is as simple as that:
def __str__(self):
return f"{self.pencilerName} ({self.publisher})"
I am in need to create two auto-generated fields:
1st field is ID and I am taking the position that is equivalent to id or we can say it is also an auto-generated field in the model.
here is the code which I am integrating:
class DeviceControl(models.Model):
vendor_id = models.ForeignKey(Vendor, on_delete=models.CASCADE)
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
position = model.[what do I write here to make it auto generated or equal to id]
def __str__(self):
return self.name
please help me to solve this.
You can override the save method to set the initial value of position:
class DeviceControlPolicy(models.Model):
vendor_id = models.ForeignKey(Vendor, on_delete=models.CASCADE)
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
position = models.IntegerField(blank=True, null=True)
def __str__(self):
return self.name
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if self.position == None:
self.position = self.id
# You need to call save two times since the id value is not accessible at creation
super().save()
I have two models, namely Applicant and LoanRequest. Whenever an Applicant instance is created, a signal is sent to a function that makes an API call. The data from the call, along with the primary key of the instance that sent the signal, is saved to as a LoanRequest.
When I save the LoanRequest, however, it gives the following error:
django.db.utils.IntegrityError: NOT NULL constraint failed: queues_loanrequest.dealer_id_id
Here's my code:
class Applicant(models.Model):
app_id = models.CharField(max_length=100)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
email = models.CharField(max_length=100)
date_posted = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.first_name + " " + self.last_name
class LoanRequest(models.Model):
loan_request_id = models.CharField(max_length=100)
app_id = models.ForeignKey(Applicant, on_delete=models.CASCADE)
FICO_score = models.CharField(max_length=100)
income_risk_score = models.CharField(max_length=100)
DTI = models.CharField(max_length=100)
date_requested = models.DateTimeField(default=timezone.now)
loan_request_status = models.CharField(max_length=100,blank=True)
dealer_id = models.ForeignKey(Dealer, on_delete=models.CASCADE,blank=True)
def credit_check(sender, instance, **kwargs):
credit_json = get_credit(instance.pk) #credit information for applicant
credit_json = json.loads(credit_json)
new_request = LoanRequest.objects.create(app_id=instance, FICO_score=credit_json["ficco-score"],
income_risk_score=credit_json["income-risk-score"],
DTI=credit_json["DTI"])
Very new to Django, would greatly appreciate help!
LoanRequest has a field
dealer_id = models.ForeignKey(Dealer, on_delete=models.CASCADE,blank=True)
Because dealer_id doesn't have null=True, creating a LoanRequest instance without supplying a dealer_id will raise the database error you've got.
You need to either supply a dealer_id in the instantiation of the LoanRequest, which should be a Dealer instance, or else change your LoanRequest model so that the dealer_id field has null=True.
Please see comment above re: using the suffix _id on a Django model foreign key - it's nearly always incorrect to do so.
Specifying blank=True without null=True is not very useful for a ForeignKey.
Use this instead:
dealer_id = models.ForeignKey(Dealer, on_delete=models.CASCADE, blank=True, null=True)
This would make the field optional. Otherwise, you would have to specify the Dealer every time you create a LoanRequest.
My API call to api/business-review/3abe3a1e-199c-4a4b-9d3b-e7cb522d6bed/ currently returns the following:
[
{
"id": "3abe3a1e-199c-4a4b-9d3b-e7cb522d6bed",
"date_time": "2016-05-31T19:18:24Z",
"review": "Another quality job, Anna has a no fuss approach to his job and clearly takes pride in what he does. Will continue to use again and again.",
"rating": "4.0",
"person": "c1cc5684-1be1-4120-9d81-05aec29f352a",
"employee": "ecdc1f99-138c-4f9f-9e1f-b959d59209aa",
"service": "1dfa408f-d5bc-4eb2-96ae-e07e7999a01a",
}
]
Now I want to create three new fields:
person_name - which grabs the first_name and last_name of the reviewer
employee_name - which grabs the first_name and last_name of the employee
service_name - which grabs the title of the service
I've tried the following so far but it doesn't create any new variables:
serializers.py
class ReviewSerializer(serializers.ModelSerializer):
"""
Class to serialize Review objects
"""
person_name = serializers.CharField(source='person.reviewer.first_name', read_only=True)
employee_name = serializers.CharField(source='person.employer.first_name', read_only=True)
service_name = serializers.CharField(source='service.title', read_only=True)
class Meta:
model = Review
fields = '__all__'
read_only_fields = 'id'
models.py
class Review(models.Model):
"""
Review model
"""
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
date_time = models.DateTimeField(blank=True, null=True, default=None)
person = models.ForeignKey(Person, null=True, default=None, related_name='reviewer')
employee = models.ForeignKey(Person, null=True, default=None, related_name='employee')
review = models.TextField(null=True, default=None)
service = models.ForeignKey(Service, null=True, default=None)
rating = models.DecimalField(max_digits=4, decimal_places=1)
class Person(models.Model):
"""
Person entity
"""
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
class Service(models.Model):
"""
Service model
"""
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
title = models.CharField(max_length=255)
Please try adding the field name explicitly instead of using __all__ which only picks up fields which are present in model and not those defined in serializer like this
fields = ['person', 'service', 'review', 'employee', 'person_name', 'service_name', 'employee_name', 'date_time']
Since you want add data to the serialized representation of your object, its better to use SerializerMethodField() for person_name, service_name and employee_name fields.
This is a read-only field. It gets its value by calling a method on
the serializer class it is attached to. It can be used to add any sort
of data to the serialized representation of your object.
Also, since the ForeignKey fields person, employee and service allow null values, you will have to handle the case when they are actually null. Otherwise, AttributeError exception will be raised on the serializer.
class ReviewSerializer(serializers.ModelSerializer):
"""
Class to serialize Review objects
"""
person_name = serializers.SerializerMethodField()
employee_name = serializers.SerializerMethodField()
service_name = serializers.SerializerMethodField()
class Meta:
model = Review
fields = ['person', 'service', 'review', 'employee', 'person_name', 'service_name', 'employee_name', 'date_time']
read_only_fields = 'id'
def get_person_name(self, obj):
try:
person_name = obj.person.first_name + obj.person.last_name
except AttributeError: # handle case if person is null
return None
else:
return person_name
def get_employee_name(self, obj):
try:
employee_name = obj.employee.first_name + obj.employee.last_name
except AttributeError: # handle case if employee is null
return None
else:
return employee_name
def get_service_name(self, obj):
try:
service_name = obj.service.title
except AttributeError: # handle case if service is null
return None
else:
return service_name
I have two model below with foreign key relation.
class City(TimeStampedModel):
uuid = models.UUIDField(default=uuid.uuid4, editable=False)
long_name = models.CharField(max_length=200)
short_name = models.CharField(max_length=200)
class Address(TimeStampedModel):
address_object = GenericForeignKey('address_content_type', 'object_id')
address1 = models.CharField(max_length=200)
address2 = models.CharField(max_length=200, null=True)
landmark = models.CharField(max_length=200, null=True)
city = models.ForeignKey(City, related_name='address_city')
And I have defined Below serializer for Address
class CityRelation(serializers.RelatedField):
def to_representation(self, value):
if isinstance(value, City):
return CitySerializer(value).data
class AddressBookSerializer(serializers.ModelSerializer):
city = CityRelation(read_only=True)
class Meta:
model = Address
fields = ('id', 'uuid', 'address1', 'address2', 'landmark', 'city')
#atomic
def create(self, validated_data):
address_book = Address(**validated_data)
address_book.save()
return address_book
def update(self, instance, validated_data):
instance.address1 = validated_data['address1']
instance.address2 = validated_data['address2']
instance.landmark = validated_data['landmark']
instance.city = validated_data['city']
instance.save()
return instance
Here While Deserializing i want to pass only city_id in JSON but while serializing i want complete city object....so i override relatedfield...but i am getting error in deserialization. I also tried to override to_internal_value() method but it did not called during deserialization. How can i do that??
I solved it...Actually i set readonly=True for city relation but with readonly only to_representation() get called not to_internal_value()...so i passed queryset...