【问题标题】:How to access parent class fields from child class in Django Python如何从 Django Python 中的子类访问父类字段
【发布时间】:2021-06-18 19:06:09
【问题描述】:

我在 Django 中的 Image 和 ProfileImage 和 ThumbnailStaticImage 类之间有以下继承:

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)

当我尝试访问应该从 Image 类继承到 ProfileImage 类的扩展变量时,它没有从父类获取该信息。

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

如果子类没有直接获取父类拥有的字段,继承的目的是什么?

如何从子类的覆盖保存方法访问父类字段?

【问题讨论】:

  • 您收到的具体什么错误?
  • 请注意,您的save 方法不会保存对象,您需要调用super().save() 才能最终将项目保存到数据库中。
  • 路径总是只等于“.png”。没有来自用户的 uuid 或路径。
  • 如何创建ProfileImages 和ThumbnailStaticImages?有某种观点,有形式?你能分享一下这方面的细节吗?
  • @SuperEye 您似乎期望uuidProfileImage.save 方法中有一个值? uuid 设置在 Image.save 方法中,当您调用 super 时,该方法在 ProfileImage.save 方法的 end 处调用

标签: python django inheritance django-models


【解决方案1】:

假设您有父模型名称 Reporter 和子模型名称 Article。现在您想从文章模型访问 Reporter。这是一个例子:

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)

让我们创建我们两个模型的对象,我们可以从我们的子模型访问我们的父(报告者类)

这里我们创建了父模型的两个对象
>>> repoter1 = Reporter(first_name='John', last_name='Smith', email='john@example.com')
>>> repoter1.save()
    
>>> repoter2 = Reporter(first_name='Paul', last_name='Jones', email='paul@example.com')
>>> repoter2.save()

#这里我们正在创建一个对象的子对象

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

#现在我们可以从子对象访问我们的父对象了

>>> print("repoter id: ",a.reporter1.id)   
>>>repoter id: 1
>>> print("repoter email: ",a.reporter1.email)   
>>>repoter email: john@example.com

您可以通过多种方式从子类访问父类字段。使用inlineformset_factory的最简单方法。

在您的 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,)

在您的 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>          

【讨论】:

    【解决方案2】:

    当使用父模型设置为abstract=True的django模型继承时,您可以使用附加到子模型的{lowercase parent model name}_ptr属性访问父模型。

    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)
    

    在上述情况下,父 Image 模型可以从 image_ptr 访问。

    p = ProfileImage.objects.all().first()
    p.image_ptr.filename
    

    【讨论】:

      猜你喜欢
      • 2019-03-01
      • 2017-10-12
      • 2022-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多