Reputation: 1312
I have following inheritance between Image and ProfileImage & ThumbnailStaticImage classes in Django :
class Image(models.Model):
uuid = models.CharField(max_length=12, default="")
extension = models.CharField(max_length=6, default=None)
filename = models.CharField(max_length=20, default=None)
path = models.CharField(max_length=64, default=None)
class Meta:
abstract = True
def save(self, *args, **kwargs):
if self.uuid is None:
self.uuid = "T" + get_random_string(11).lower()
super(Image, self).save(*args, **kwargs)
def delete(self, *args, **kwargs):
delete_message_send(self.path)
super(Image, self).delete(*args, **kwargs)
class ProfileImage(Image):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def save(self, *args, **kwargs):
if self.extension is None:
self.extension = ".png"
if self.filename is None:
self.filename = self.uuid + self.extension
if self.path is None:
self.path = self.user.path + "/" + self.filename
super(ProfileImage, self).save(*args, **kwargs)
class ThumbnailStaticImage(Image):
video = models.ForeignKey(Video, on_delete=models.CASCADE, default=None)
def save(self, *args, **kwargs):
if self.extension is None:
self.extension = ".png"
if self.filename is None:
self.filename = self.uuid + self.extension
if self.path is None:
self.path = settings.STORAGE.THUMBNAILDIRECTORY + "/" + self.filename
super(ThumbnailStaticImage, self).save(*args, **kwargs)
When I try to access the extension variable that should be inherited from Image class to ProfileImage class, it does not get that information from parent class.
class CustomProfileImageSignedURL(APIView):
@method_decorator(login_required(login_url='/login/'))
def post(self, request):
profileimage = ProfileImage.objects.
create(user=request.user)
signed_url = get_signed_url_for_upload(
path=profileimage.path,
content_type='image/png')
logging.debug(signed_url);
return Response({
"custom_profile_image_signed_url":signed_url,
"image_uuid":profileimage.uuid})
What is the purpose of inheritance if the child class does not get the fields that parent class has directly?
How can I access the parent class fields from child class' overriding save method ?
Upvotes: 3
Views: 5174
Reputation: 43870
When using django model inheritance where the parent model is not set to abstract=True
you can access the parent using {lowercase parent model name}_ptr
attribute attached to the child model.
class Image(models.Model):
uuid = models.CharField(max_length=12, default="")
extension = models.CharField(max_length=6, default=None)
filename = models.CharField(max_length=20, default=None)
path = models.CharField(max_length=64, default=None)
class ProfileImage(Image):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
In the case above the parent Image
model can be accessed from the from image_ptr
.
p = ProfileImage.objects.all().first()
p.image_ptr.filename
Upvotes: 2
Reputation: 1637
Let assume you have parent model name Reporter and Child model name Article. Now you want to access Reporter from Article model. here is an example:
class Reporter(models.Model): #this is our parent model
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
class Article(models.Model): #this is our child model
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
Let create objects of our two models and we can access our parent(Reporter class) from our child model
>>> repoter1 = Reporter(first_name='John', last_name='Smith', email='[email protected]')
>>> repoter1.save()
>>> repoter2 = Reporter(first_name='Paul', last_name='Jones', email='[email protected]')
>>> repoter2.save()
#here we are creating an child of object
>>> from datetime import date
>>> a = Article(id=None, headline="This is a test", pub_date=date(2005, 7, 27), reporter=repoter1) #this is a child object of repoter1
>>> a.save()
#now we can access our parent from child object
>>> print("repoter id: ",a.reporter1.id)
>>>repoter id: 1
>>> print("repoter email: ",a.reporter1.email)
>>>repoter email: [email protected]
There are lot of way you can access parent class fields from child class. The easiest way to use inlineformset_factory.
in your froms.py:
forms .models import your model
class ParentFrom(froms.From):
# add fields from your parent model
ImageFormSet = inlineformset_factory(your parent model name,Your Child model name,fields=('image',# add fields from your child model),extra=1,can_delete=False,)
in your views.py
if ParentFrom.is_valid():
ParentFrom = ParentFrom.save(commit=False)
ImageFormSet = ImageFormSet(request.POST, request.FILES,)
if ImageFormSet.is_valid():
ParentFrom.save()
ImageFormSet.save()
return HttpResponseRedirect(#your redirect url)
#html
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
#{{ImageFormSet.errors}} #if you want to show ImageFormSet error
{{ImageFormSet}}
{{form}}
</form>
Upvotes: 2