【问题标题】:Is there a better way to write this code so DRY can be maintained?是否有更好的方法来编写此代码以便可以维护 DRY?
【发布时间】:2021-05-25 15:38:23
【问题描述】:

我有 2 个模型

  1. 游览以保存游览

  2. TourImage 保存与 Tour 相关的图片

    class Tour(models.Model):
        name = models.CharField(max_length=50)
    
    class TourImage(models.Model):
        tour = models.ForeignKey(Tour, on_delete=models.CASCADE)
        image = models.FileField(upload_to='images/')
    

在我的 views.py 文件中,我有以下代码来保存游览和游览图像

class CreateTourView(CreateView):
    model = Tour
    template_name = "create_tour.html"
    fields = "__all__"

    def form_valid(self, form):
        tour = form.save()
        for image in self.request.FILES.getlist("extra_images"):
            TourImage.objects.create(tour=tour, image=image)
    return super().form_valid(form)

HTML 表单如下所示

<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form | crispy }}
<input type="file" name="extra_images" multiple />
<input type="submit" value="Save" />
</form>

这很好,图像保存在数据库中。

但我还想添加选项来编辑旅游并添加额外的图像,所以UpdateView代码如下

class TourUpdateView(UpdateView):
    model = Tour
    template_name = "update_tour.html"
    fields = "__all__"

    def form_valid(self, form):
        tour = form.save()
        for image in self.request.FILES.getlist("extra_images"):
            TourImage.objects.create(tour=tour, image=image)
        return super().form_valid(form)

.form_valid() 方法对于 CreateView 和 UpdateView 是相同的。

有没有更好的方法来编写代码以避免重复代码?

【问题讨论】:

    标签: django django-forms django-class-based-views django-file-upload


    【解决方案1】:

    你创建一个mixin

    class TourImageMixin:
        model = Tour
    
        def form_valid(self, form):
            tour = form.save()
            for image in self.request.FILES.getlist('extra_images'):
                TourImage.objects.create(tour=tour, image=image)
            return super().form_valid(form)

    然后你把它混合在两个视图中:

    class CreateTourView(TourImageMixin, CreateView):
        template_name = 'create_tour.html'
        fields = '__all__'
    
    class TourUpdateView(TourImageMixin, UpdateView):
        template_name = "update_tour.html"
        fields = '__all__'

    事实上,Django 的视图,例如 ListView [classy CBV] 是用定义某些行为的 mixins 构造的。对于ListView,使用MultipleObjectTemplateResponseMixin [Django-doc]TemplateResponseMixin [Django-doc]MultipleObjectMixin [Django-doc]

    【讨论】:

    • 这很好用,感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 2020-01-29
    • 1970-01-01
    • 2013-01-14
    相关资源
    最近更新 更多