Django:添加一个允许多个图像的字段

eufgjt7s  于 2023-05-23  发布在  Go
关注(0)|答案(1)|浏览(147)

Forms.py

class SellerForm(forms.ModelForm):
username = forms.CharField()
class Meta:
model = Seller
fields = [
'username',
'first_name',
'last_name',
'country',
'image_of_seller',
'city',
'date_of_birth',
'describe_yourself'
]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['username'].initial = self.instance.seller.username
    
    @transaction.atomic
    def save(self, commit=True):
        seller = super().save(commit=False)
        user = seller.seller
        self.instance.seller.username = self.cleaned_data['username']
    
        if commit:
            seller.save()
            user.save()
    
        return seller

Views.py

class SellerUpdateView(UpdateView):
model = Seller
form_class = SellerForm
template_name = 'core/seller_update_form.html'

    def get_object(self, queryset=None):
        return self.request.user.seller

Models.py

class Seller(models.Model):
seller = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50, null=False, blank=False)
last_name = models.CharField(max_length=50, default=False)
country = models.CharField(max_length=50, null=False, blank=False)
identification = models.ImageField(null=False, blank=False)
image_of_seller =  models.ImageField(null=False, blank=True) # I want this to accept multiple files, which are images.
city = models.CharField(max_length=30)
date_of_birth = models.DateField(null=False, blank=False)
describe_yourself = models.TextField(null=False, blank=False)
slug = models.SlugField(unique = True, blank = True)

    def __str__(self):
        return self.seller.username
    
    def save(self, *args, **kwargs):
        self.slug = slugify(self.seller.username)
        super().save(*args, **kwargs)

我知道我可以创建另一个模型,用ForeignKey指向Seller模型,然后在创建ModelAdmin时内联。但是有没有办法把这个作为表单的替代呢?我希望用户能够更新他们的图片。

更新

我正在考虑一些行为类似于StackedInline的东西,就像下面的例子。但不是在admin中呈现,而是在SellerForm中呈现。

class Seller(models.Model):
    #changed from seller to user, just for readability. 
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=50, null=False, blank=False)
    last_name = models.CharField(max_length=50, default=False)
    country = models.CharField(max_length=50, null=False, blank=False)
    identification = models.ImageField(null=False, blank=False)
    city = models.CharField(max_length=30)
    date_of_birth = models.DateField(null=False, blank=False)
    describe_yourself = models.TextField(null=False, blank=False)
    slug = models.SlugField(unique = True, blank = True)
    age = models.IntegerField(default=0)

    @property
    def calculate_age(self):
        today = datetime.date.today()
        year = today.strftime("%Y")
        current_year = int(year)
        user_year = int(self.date_of_birth.year)
        age = current_year - user_year
        self.age = age 
        return age
    
    def __str__(self):
        return self.seller.username
    
    def save(self, *args, **kwargs):
        self.calculate_age
        self.slug = slugify(self.seller.username)
        super().save(*args, **kwargs)

class ImageOfSeller(models.Model):
    seller = models.ForeignKey(Seller, on_delete=models.CASCADE)
    Image = models.ImageField()

# Admin.py 

class ImageSellerInline(admin.StackedInline):
    model = ImageOfSeller 
    can_delete = True 
    verbose_name_plural = 'seller_image'
    extra = 0

class SellerAdmin(admin.ModelAdmin):
    inlines = [
        ImageSellerInline,
    ]
admin.site.register(Seller, SellerAdmin)
kfgdxczn

kfgdxczn1#

根据您的评论和我的理解,您可以通过在模型中将图像字段设置为ArrayField来实现这一点:

class Seller(models.Model):
    images = models.ArrayField(default=list)

然后你可以让它像这样在你的表单中工作:

class SellerForm(forms.ModelForm):
    images = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}), required=False)

但是你必须在视图中手动处理数据:

form = SellerForm(request.POST, request.FILES, instance=seller)
        if form.is_valid():
            seller = form.save(commit=False)
            images = request.FILES.getlist('images')
            for image in images:
                seller.images.append(image)
            seller.save()

但我不推荐这种方法。更好的方法是使用ImageField和FK创建另一个模型到您的主模型。然后你可以使用django表单集来处理多个示例和内联,你可以找到很多例子,这是从主文档:
https://docs.djangoproject.com/en/4.2/topics/forms/formsets/

相关问题