I have a class named Property with a field property_type, i wana autofill this field when i create one of the other models who have onetoone relationship with Property
I want the when i create a Apartment in django admin for exp the property_type in Property should autofill with the "Apartment", when i create Villa in django admin it should autofill with "villa"
class Property(models.Model):
created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="agent_of_property")
district_id = models.ForeignKey(District, on_delete=models.CASCADE)
slug = models.SlugField(max_length=255, unique=True)
property_type = models.CharField(choices=PROPERTY_TYPE, max_length=20)
title = models.TextField(verbose_name="Titulli", help_text="Vendos titullin e njoftimit", max_length=500)
description = models.TextField(verbose_name="Pershkrimi", help_text="Vendos pershkrimin",max_length=1000)
address_line = models.CharField(verbose_name="Adresa", help_text="E nevojeshme",max_length=255)
price = models.IntegerField()
area = models.IntegerField()
views = models.IntegerField(default=0)
documents = models.CharField(verbose_name="Dokumentacioni", help_text="Dokumentat", max_length=255)
status = models.BooleanField(default=True)
activity = models.CharField(max_length=20, choices=ACTION_OPTION)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = "Prona"
verbose_name_plural = "Pronat"
def get_absolute_url(self):
return reverse("pronat:property_detail", args=[self.slug])
def __str__(self):
return self.title
class Apartment(Property):
property_id = models.OneToOneField(Property, on_delete=models.CASCADE, parent_link=True, primary_key=True)
floor = models.IntegerField(default=0)
room_num = models.IntegerField(default=0)
bath_num = models.IntegerField(default=0)
balcony_num = models.IntegerField(default=0)
class Meta:
verbose_name = "Apartament"
verbose_name_plural = "Apartamentet"
def save(self, *args, **kwargs):
self.property_type = "Apartment"
class Villa(Property):
property_id = models.OneToOneField(Property, on_delete=models.CASCADE, parent_link=True, primary_key=True)
living_room = models.IntegerField(default=1)
floors = models.IntegerField(default=1)
room_num = models.IntegerField(default=1)
bath_num = models.IntegerField(default=1)
balcony_num = models.IntegerField(default=0)
class Meta:
verbose_name = "Vila"
verbose_name_plural = "Vilat"```
I don't understand what your are doing. If you are inheriting from Property models in Apartment just remove OneToOneField and your save method would be
def save(self, *args, **kwargs):
self.property_type = 'Apartment'
super().save(*args, **kwargs)
But if you really want to use OneToOneField, replace Property inherit with models.Model and your save method should look like this.
def save(self, *args, **kwargs):
self.property_id.property_type = 'Apartment'
self.property_id.save()
super().save(*args, **kwargs)
For 2nd case you can also use django signal
from django.db.models.signal import post_save
# ...
def populate_property_type(sender, created, instance, **kwargs):
if sender.__name__ == 'Apartment':
instance.property_id.property_type = 'Apartment'
instance.property_id.save()
# condition for Villa
post_save.connect(populate_property_type, sender=Apartment)
post_save.connect(populate_property_type, sender=Villa)
I would suggest that you should add field in Appartment table with the name appartment_type and remove property_type from Property. But If you don't want to do that then Two ways are possible for your case.
1.When you are adding values from Django admin, you should also add the property_type from Admin.In that case you don't need to override save method.
Register your Property and Appartment Table in one view.
Make the admin Tables of Property and Appartment for admin view. Then register it like this way i-e
admin.site.register(PropertyAdmin, AppartmentAdmin)
and add values into both tables.
2: Simply override the save method and add this
def save(self, *args, **kwargs):
self.property_id.property_type = 'Apartment' # you should add other field in Appartment table just avoid hard coded 'Apartment'
self.property_id.save()
super().save(*args, **kwargs)
Related
I'm trying to query fields from another model in Django .
I'm able to fetch the user information using the following method
def student(self, *args, **kwargs):
std_name = Attendance.objects.get(roll=self.roll)
return std_name.name
Now I need to find the student's assigned teacher from a different table, I need to fetch it only using the student name which I got using student() as I don't have any variable in my current table to reference it to fetch that information from the new table.
def teacher(self, *args, **kwargs):
teacher_name = staff.objects.get(student=self.student)
return teacher_name.name
But the above method is not working properly and is not populating the fields in my admin.py page . Can someone help me in fixing this issue
#Attendance model
class Attendance(models.Model):
class Meta:
verbose_name = 'Attendance'
verbose_name_plural = ''Attendance''
Group = models.TextField(max_length=15, blank=True, null=True)
Year = models.IntegerField(blank=True,null=True)
roll = models.IntegerField(blank=True,null=True)
Date = models.TextField(max_length=15, blank=True, null=True)
name = models.TextField(max_length=10, blank=True, null=True)
Presence = models.TextField(max_length=15, blank=True, null=True)
def student(self, *args, **kwargs):
std_name = Attendance.objects.get(roll=self.roll)
return std_name.name
def teacher(self, *args, **kwargs):
teacher_name = staff.objects.get(student=self.student)
return teacher_name.name
#staff model
class staff(models.Model):
class Meta:
verbose_name = staff
verbose_name_plural = ''staff''
name = models.TextField(max_length=10, blank=True, null=True)
degree = models.TextField(max_length=15, blank=True, null=True)
subject = models.IntegerField(blank=True,null=True)
experience = models.IntegerField(blank=True,null=True)
student = models.TextField(max_length=15, blank=True, null=True)
I've multiple models in my Django project but only this given below model creating another instance on update instead of save. This is happening in Django's Admin panel, not on my custom UI. When I remove my save() method then it works fine but this way I won't be able to create slug.
Does anybody know what I'm doing wrong in here
class Course(models.Model):
title = models.CharField(max_length=200)
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='category')
slug = models.SlugField(max_length=200, unique=True, primary_key=True, auto_created=False)
short_description = models.TextField(blank=False, max_length=60)
description = models.TextField(blank=False)
outcome = models.CharField(max_length=200)
requirements = models.CharField(max_length=200)
language = models.CharField(max_length=200)
price = models.FloatField(validators=[MinValueValidator(9.99)])
level = models.CharField(max_length=20)
application_link = models.URLField(max_length=1000, blank=True, null=True)
brochure = models.FileField(upload_to='brochures/', blank=True, null=True)
thumbnail = models.ImageField(upload_to='thumbnails/')
video_url = models.CharField(max_length=100)
is_session_available = models.BooleanField(default=False)
session_url = models.CharField(max_length=250, default='')
is_published = models.BooleanField(default=True)
created_at = models.DateTimeField(default=now)
updated_at = models.DateTimeField(default=now)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Course, self).save(*args, **kwargs)
instead of overriding save method you could do this:
admin.py
class CourseAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('title',)}
admin.site.register(Course, CourseAdmin)
It is happening because it will generate new slug every time. You can do something like this:
def generate_slug(self):
self.slug = slugify(self.name)
def save(self, *args, **kwargs):
if not self.slug:
self.generate_slug() # This will generate slug.
return super().save(*args, **kwargs)
In this project, I have two models Student and Parent related to each other through one to one field.
In Parent serializer, I want to add Students attributes like age. I am thinking of using SerializerMethodField for both cases is their any better way to do it?
I am not getting the queries on how to get the object attributes and little explanation would be great.
Here what I have done till now.
Models.py
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, default=None)
batch = models.ForeignKey(Batch, on_delete=models.CASCADE, null=True, related_name='students')
email = models.EmailField(null=True)
phone_number = models.CharField(max_length=10, null=True)
dob = models.DateField(blank=True, null=True, help_text="Enter in the following format : YYYY-MM-DD")
address = models.TextField(max_length=150, null=True)
age = models.IntegerField(blank=True)
image = models.ImageField(upload_to='profile_pictures', default='student_image.png', blank=True)
#property
def remarks(self):
return self.remark_set.all()
#property
def marks(self):
return self.marks_set.all()
def __str__(self):
return self.user.firstName + ' ' + self.user.lastName
class Parent(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, default=None)
child = models.ForeignKey(Student, on_delete=models.CASCADE)
email = models.EmailField(null=True)
phone_number = models.CharField(max_length=10, null=True)
address = models.TextField(max_length=150, null=True)
image = models.ImageField(upload_to='profile_pictures', default='student_image.png', blank=True)
def __str__(self):
return self.user.firstName + ' ' + self.user.lastName
Serilaizer.py
class ParentSerializer(serializers.HyperlinkedModelSerializer):
student_age = serializers.SerializerMethodField()
student_batch = serializers.SerializerMethodField()
parent_name = serializers.SerializerMethodField()
class Meta:
model = Parent
fields = "__all__"
def get_student_age(self, obj):
return Parent.objects.get(child__age = self.obj.user.child)
def get_student_batch(self, obj):
return Parent.objects.get(child__bacth = self.obj.user.child)
def get_parent_name(self, user):
return Parent.objects.get(user=self.request.user)
Views.py
class ParentView( mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet):
queryset = Parent.objects.all()
serializer_class = serializers.ParentSerializer
first way:
from apps.models import Student, parent
class BasicUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = "__all__"
class BasicStudentSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = "__all__"
class ParentSerializer(serializers.ModelSerializer):
user = BasicUserSerializer(read_only=True,many=False)
child = BasicStudentSerializer(read_only=True, many=True)
class Meta:
model = Parent
fields = '__all__'
you can do this way . its replace a serializer field that you want and if parent have several child then in child's field you have new all child's information as dictionary.
================================================================
second way is use HyperLinkModel .
class ParentSerializer(serializers.ModelSerializer):
user = serializers.HyperlinkedRelatedField(read_only=True,many=False)
child = serializers.HyperlinkedRelatedField(read_only=True, many=True)
class Meta:
model = Parent
fields = '__all__'
but notice that in first way you will have a independent serializer class that every time you need to serialize model class that related to User or Child you can use them simply.
I have a little problem with display subcategories belongs only in specific categories. For example: I have a categories: Business, Factory, Health ... and after I can add subcategories for example Own Company in category Business. In this case if I choose category Business I need to have only visible subcategories belongs to this category. How to make it?
This is my code.
models.py
from django.db import models
from slugify import slugify
class Kategoria(models.Model):
name = models.CharField(max_length=50, unique=True, verbose_name='Nazwa kategorii')
slug = models.SlugField(verbose_name='Adres SEO')
class Meta:
verbose_name_plural = 'Kategorie'
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Kategoria, self).save(*args, **kwargs)
def __str__(self):
return self.name
class Subkategoria(models.Model):
category = models.ForeignKey('Kategoria', related_name='subkategoria', on_delete=models.CASCADE, blank=True, null=True, verbose_name='Kategoria główna')
name = models.CharField(max_length=50)
class Meta:
verbose_name_plural = 'Subkategorie'
def __str__(self):
return self.name
class Strona(models.Model):
name = models.CharField(max_length=250, verbose_name='Nazwa strony')
slug = models.SlugField(verbose_name='Adres SEO')
www = models.CharField(max_length=200, verbose_name='Adres strony', unique=True)
content = models.TextField(verbose_name='Opis')
category = models.ForeignKey('Kategoria', verbose_name='Kategoria', on_delete=models.CASCADE)
subcategory = models.ForeignKey('Subkategoria', verbose_name='Subkategoria', on_delete=models.CASCADE)
publish = models.DateField(auto_now=False, auto_now_add=False)
class Meta:
verbose_name_plural = 'Strony'
def __str__(self):
return self.name
When saving my table Django does not seem to be assigning any primary key? I'm I missing something?
class Campaign(models.Model):
campaignid = models.CharField(max_length=255, primary_key=True, db_column='campaignID')
name = models.CharField(max_length=105)
active = HibernateBooleanField(default=False)
created = models.DateTimeField()
modified = models.DateTimeField(null=True, blank=True)
companyid = models.ForeignKey(Company, null=True, db_column='companyID', blank=True)
class Meta:
db_table = u'campaign'
def __unicode__(self):
return self.name
Ok as my model was generated from an existing table using guid I had to keep it as CharField adding this seemed to work:
def save(self, *args, **kwargs):
if not self.campaignid:
self.campaignid = hashlib.sha1(str(random.random())).hexdigest()
super(Campaign, self).save(*args, **kwargs)