0

我在視圖中有一些問題,我創建了CBV CreateView。所以它工作良好,它保存了表單,但是我錯誤'ProductForm'對象沒有屬性'save_m2m,如果我不使用form.save_m2m它不會將圖像添加到我的產品,但會將其添加到媒體。表單對象沒有屬性'save_m2m'django

所以在這裏我們有model.py

class Product(models.Model): 
    class Meta: 
     verbose_name = 'Продукт' 
     verbose_name_plural = 'Продукты' 

    shop = models.ForeignKey(Shop, verbose_name='Название магазина') 
    category = models.ForeignKey(Category, verbose_name='Название категории') 
    title = models.CharField(max_length=255, verbose_name='Название товара') 
    slug = models.SlugField(_("Название на транслите"), max_length=50, unique=True, blank=True, null=True) 
    price = models.DecimalField(null=True, blank=True, verbose_name='Цена', decimal_places=0, max_digits=10) 
    sell_count = models.PositiveIntegerField(_("Количество продаж"), default=0, null=True, blank=True) 
    discount = models.PositiveIntegerField(null=True, blank=True, verbose_name='Скидка') 
    currency = models.CharField(null=True, max_length=255, verbose_name='Валюта', default='сом') 
    quantity = models.IntegerField(verbose_name='Количество', default=0) 
    delivery_type = models.CharField(verbose_name='Вид доставки', choices=DELIVERY_TYPES, default='self', 
            max_length=255) 
    delivery_cost = models.FloatField(verbose_name='Стоимость доставки', default=0, null=True, blank=True) 
    # settings = models.ManyToManyField('ProductSettings', verbose_name='Характеристика') 
    availability = models.CharField(_("Наличие"), max_length=100, choices=AVAILABILITY_TYPES, default='available') 
    published = models.BooleanField(default=True) 
    short_description = models.TextField(max_length=300, null=True, blank=True, 
             verbose_name='Короткое описание товара до 300 символов') 
    long_description = RichTextUploadingField(null=True, blank=True, verbose_name='Полное описание') 
    images = models.ManyToManyField('Media', verbose_name='Изображения продукта', blank=True) 
    objects = ProductPublishedManager() 



class Media(models.Model): 
    class Meta: 
     verbose_name = "Изображение" 
     verbose_name_plural = "Изображения" 

    image = models.ImageField(upload_to='images') 

在這裏,我有forms.py

class ProductForm(forms.ModelForm): 
    class Meta: 
     model = Product 
     exclude = ['slug', 'objects', 'sell_count'] 

    removed_images = forms.CharField(required=False) 
    uploaded_images = forms.CharField(required=False) 

    def __init__(self, *args, **kwargs): 
     self.user = kwargs['initial']['user'] 
     super(ProductForm, self).__init__(*args, **kwargs) 
     self.fields['shop'].queryset = Shop.objects.filter(user__in=[self.user.id]) 
     for field in iter(self.fields): 
      self.fields[field].widget.attrs.update({ 
       'class': 'form-control' 
      }) 

這裏是views.py

class ProductCreateView(LoginRequiredMixin, AddProductMixin, CreateView): 
    form_class = ProductForm 
    template_name = 'product/product_form.html' 

    def get_success_url(self): 
     return reverse('shops:detail', args=(self.object.shop.slug,)) 

    def get_initial(self): 
     return {'shop': Shop.objects.get(slug=self.kwargs['slug']), 
       'user': self.request.user 
       } 

    def form_valid(self, form, **kwargs): 
     product = form.instance 
     product.slug = slugify(form.instance.title) 
     product.shop = Shop.objects.get(slug=self.kwargs['slug']) 
     form.save() 
     if form.cleaned_data['uploaded_images']: 
      if ',' in form.cleaned_data['uploaded_images']: 
       for item in form.cleaned_data['uploaded_images'].split(','): 
        try: 
         media = Media.objects.get(id=int(item)) 
         product.images.add(media) 
        except ObjectDoesNotExist: 
         pass 
      else: 
       try: 
        media = Media.objects.get(id=int(form.cleaned_data['uploaded_images'])) 
        product.images.add(media) 
       except ObjectDoesNotExist: 
        print('error') 
     form.save_m2m() 
     if form.cleaned_data['removed_images']: 
      for item in form.cleaned_data['removed_images'].split(','): 
       try: 
        media = Media.objects.get(id=int(item)) 
        image_path = MEDIA_ROOT + '/' + media.image.name 
        os.remove(image_path) 
        media.delete() 
       except ObjectDoesNotExist: 
        pass 

     return super(ProductCreateView, self).form_valid(form) 
+0

我在代碼中沒有看到'commit = False'。 Django只添加save_m2m屬性,當form.save(commit = False)被調用... –

+0

o對不起,如果我使用form.save(commit = False),它給這個exeption「對象需要爲字段」product「在這之前可以使用多對多關係。「可能是我必須在另一個地方使用form.save(commit = False),但我不知道我必須在哪裏使用這個功能。 –

+0

yes .. do'obj = form.save(commit = False)'然後做'obj.save()'然後'form.save_m2m()' –

回答

0

嘗試編輯您的看法是這樣,

def form_valid(self, form, **kwargs): 
    product = form.save(commit=False) 
    product.slug = slugify(form.instance.title) 
    product.shop = Shop.objects.get(slug=self.kwargs['slug']) 
    product.save() 
    if form.cleaned_data['uploaded_images']: 
     if ',' in form.cleaned_data['uploaded_images']: 
      for item in form.cleaned_data['uploaded_images'].split(','): 
       try: 
        media = Media.objects.get(id=int(item)) 
        product.images.add(media) 
       except ObjectDoesNotExist: 
        pass 
     else: 
      try: 
       media = Media.objects.get(id=int(form.cleaned_data['uploaded_images'])) 
       product.images.add(media) 
      except ObjectDoesNotExist: 
    # **Edited here**.. 
    product.save_m2m() 
    if form.cleaned_data['removed_images']: 
     for item in form.cleaned_data['removed_images'].split(','): 
      try: 
       media = Media.objects.get(id=int(item)) 
       image_path = MEDIA_ROOT + '/' + media.image.name 
       os.remove(image_path) 
       media.delete() 
      except ObjectDoesNotExist: 
       pass 

    return super(ProductCreateView, self).form_valid(form) 
+0

它沒有工作 –

+0

有沒有錯誤?或者它只是沒有保存? – zaidfazil

+0

我編輯了代碼 – zaidfazil

0

嘗試像這樣

form.save(commit=False) 
form.save_m2m() 
0

ve rewrote my model with adding new varialble to Media. And in view i已經從

product.images.add(media) 

改爲

product.media_set.add(media) 

和我的模型

class Media(models.Model): 
class Meta: 
    verbose_name = "Изображение" 
    verbose_name_plural = "Изображения" 

image = models.ImageField(upload_to='images') 
products = models.ManyToManyField(Product) 

def __str__(self): 
    return self.image.url 

在類中產品i中刪除了var圖像