How to add Two auto-generated field in one model in Django - python

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()

Related

How can I set foreign key from post request in Django

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'], ...)

create fields according to a number in another field in django

I have 3 tables(Subjects, Sectors , Zones), one subject has many sectors and one sector has many zones
my auestion is how should i implent my models and views and serializers in sort of returning a json file indicating the name of the subject and the number of sectors and the number of zones in every sector. I tried this :
class Subject(models.Model):
name = models.CharField(max_length=200)
host = models.CharField(max_length=200,
primary_key=True)
nb_sectors = models.IntegerField(null=True)
def __str__(self):
return self.name
class Sector(models.Model):
name = models.CharField(max_length=200)
task = models.ForeignKey(Subject
,on_delete=models.CASCADE)
nb_zones = models.IntegerField(null=True)
def __str__(self):
return self.name
class Zone(models.Model):
name = models.CharField(max_length=200)
sector = models.ForeignKey(Sector
,on_delete=models.CASCADE)
status= ChoiceField(choices)
def __str__(self):
return self.name
You can define a ManyToManyField in the Subject table to the Sector table and in the Sector table to the Zone table. So your models.py will look like,
class Subject(models.Model):
name = models.CharField(max_length=200)
host = models.CharField(max_length=200,primary_key=True)
# other atribs...
sectors = models. ManyToManyField('Sector')
#property
def sectors_count(self):
return (self.sectors.count())
def __str__(self):
return self.name
class Sector(models.Model):
name = models.CharField(max_length=200)
# other atribs...
zones = models.ManyToManyField('Zone')
#property
def zones_count(self):
return (self.zones.count())
def __str__(self):
return self.name
class Zone(models.Model):
name = models.CharField(max_length=200)
status= ChoiceField(choices)
def __str__(self):
return self.name
In your subject serializer you can either specify a link to sector serializer
class SubjectSerializer(serializers.ModelSerializer):
sectors = SectorSerializer(read_only=True, many=True)
sectors_count = serializers.ReadOnlyField() # this is defined as property in the model
class Meta:
model = Subject
fields = '__all__'
class SectorSerializer(serializers.ModelSerializer):
zones_count = serializers.ReadOnlyField() # this is defined as property in the model
class Meta:
model = Sector
fields = '__all__'
Or you can also use a serializer method filed and iterate through all the zone object
class SubjectSerializer(serializers.ModelSerializer):
sectors = serializers.SerializerMethodField(required=False)
sectors_count = serializers.ReadOnlyField() # this is defined as property in the model
class Meta:
model = Subject
fields = '__all__'
def get_sectors(self, obj):
data = []
for sector in obj.sectors.all():
data.append({
'zones_count': sector.zones_count,
'name': sector.name
})
return data
If you want to re-use the sector serializer then you can go with the first one.

ValueError: Cannot assign "<Truckdb: Truckdb object (1)>": "Quiz.truck_name" must be a "truck_name" instance

I am trying to create an instance in my app like this:
Views.py
new_quiz = Quiz.objects.create(owner=request.user, comments="Autogenerated", truck_type=truck_type_object,
truck_name=chosen_truck_object)
where chosen_truck_object is this:
chosen_truck_object = Truckdb.objects.filter(display_name=chosentruck)[0]
And Models.py
class Quiz(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='quizzes')
comments = models.TextField(max_length=256, blank=True)
truck_type = models.ForeignKey(truck_type, on_delete=models.CASCADE, related_name='trucks')
truck_name = models.ForeignKey(truck_name, on_delete=models.SET_NULL, null=True)
class truck_type(models.Model):
name = models.CharField(max_length=30)
color = models.CharField(max_length=7, default='#007bff')
def __str__ (self):
return self.name
class truck_name(models.Model):
truck_type = models.ForeignKey(truck_type, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__ (self):
return self.name
How can I pass the truck_type and truck_name instance to the Quiz model in Quiz.objects.create ?
Firstly you need to follow the naming convention guidelines, so your models' name must be camelcase doc as like:
class TruckType(models.Model):
name = models.CharField(max_length=30)
color = models.CharField(max_length=7, default='#007bff')
def __str__ (self):
return self.name
class TruckName(models.Model):
truck_type = models.ForeignKey(TruckType, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__ (self):
return self.name
And then please migrate your database and then for your problem you need to take TruckName object instead of Truckdb.
chosen_truck_object = TruckName.objects.filter(display_name=chosentruck)[0]
instead of filter use get method chosen_truck_object = TruckName.objects.get(display_name=chosentruck) it will save

Django show only the values in the selected field

So in my models.py I have this:
class Profesie(models.Model):
titlu = models.CharField(max_length=100)
def __str__(self):
return self.titlu
class Domeniu(models.Model):
profesie = models.ForeignKey(Profesie)
titlu = models.CharField(max_length=100)
def __str__(self):
return self.titlu
class Anunt(models.Model):
titlu = models.CharField(max_length=150)
user = models.ForeignKey('auth.User', related_name='anunturi')
profesie = models.ForeignKey(Profesie)
domeniu = models.ForeignKey(Domeniu)
In the form when the user selects the field profesie, and then domeniu, for the domeniu field it should only display the values that are in the Profesie table. How can I accomplish that?

Django ORM Object has no attribute '_set'

I assumed Django automatically created the _set for me but I'm the following error.
for dep_badge in self.badge.badge_set.all():
AttributeError: 'Badge' object has no attribute 'badge_set'
Models:
class Badge(RewardBase):
"""
Represents a Badge.
"""
name = models.CharField(max_length=60, help_text="Name of the badge")
description = models.TextField(max_length=150)
reputation_value = models.IntegerField(help_text="Value given in accumulate reputation", default=0)
reputation_prerequisite = models.IntegerField(help_text="Point value needed to obtain", default=0)
difficulty_level = models.IntegerField(choices=STATUS_TYPES, default=STATUS_EASY,
help_text="Badge difficulty")
class Award(RewardBase):
"""
Representation of a badge awarded to a user.
"""
description = models.CharField(max_length=100, choices=STATUS_TYPES, default=STATUS_GENERAL)
value = models.IntegerField(default=0)
read = models.BooleanField(default=False, help_text="Has the user read this?")
created = models.DateTimeField(blank=True, null=True, editable=False)
hidden = models.BooleanField(default=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
badge = models.ForeignKey("Badge")
def save(self, *args, **kwargs):
super(Award, self).save(*args, **kwargs)
for dep_badge in self.badge.badge_set.all():
dep_badge.check_prerequisites(self.user, sel
f.badge, self)
Badge has no badge_set.No foreign key to itself. Maybe u mean award_set?
It looks like you intend to do
self.badge.award_set.all()
instead. badge_set is looking for a reverse relationship to the Badge model, which does not exist.

Categories

Resources