Имею таблицу в Django с ManyToMany field. Не могу понять, как обновить запись в таблице
Имею таблицу с постами у которых может быть несколько категорий, и таблицу с самими категориями, у которых может быть несколько постов. models.py:
class Category(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=25)
body = models.TextField()
image = models.ImageField(blank=True)
created_on = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
categories = models.ManyToManyField('Category', related_name='posts', blank=True)
profile = models.ForeignKey('Profile', verbose_name='User',
on_delete=models.CASCADE,
related_name='profile')
def __str__(self):
return self.title
views.py:
class ListCategoryView(generic.ListView):
def get(self, request, *args, **kwargs):
category = kwargs['category']
posts = Post.objects.filter(categories__name__contains=category).order_by('-created_on')
context = {
"category": category,
"posts": posts
}
return render(request, "list_category.html", context)
class ListPostView(generic.ListView):
model = Post
context_object_name = 'posts'
template_name = 'list_post.html'
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.order_by('-created_on')
return queryset
class CreatePostView(LoginRequiredMixin, generic.CreateView):
model = Post
template_name = 'create_post.html'
form_class = PostDocumentForm
def post(self, request, *args, **kwargs):
blog_form = PostDocumentForm(request.POST, request.FILES)
if blog_form.is_valid():
categories = Category.objects.create(name=blog_form.cleaned_data['categories'])
title = blog_form.cleaned_data.get('title')
body = blog_form.cleaned_data.get('body')
profile = request.user.profile
image = self.get_image(blog_form)
instance = Post.objects.create(title=title, body=body, profile=profile, image=image)
instance.categories.set([categories])
return HttpResponseRedirect('/blog/')
return render(request, 'create_post.html', context={'form': blog_form})
def get_image(self, form):
image = form.cleaned_data.get('image')
return image
class EditPostView(generic.UpdateView):
form_class = PostDocumentForm
model = Post
template_name = 'edit_post.html'
success_url = '/blog/'
forms.py:
class CategoryDocumentForm(forms.ModelForm):
class Meta:
model = Category
fields = ('name',)
class PostDocumentForm(forms.ModelForm):
categories = forms.CharField(min_length=3, max_length=100, required=False)
class Meta:
model = Post
fields = ('title', 'body', 'image', 'categories')
Не могу понять, как обновить пост, чтоб обновились и категории. Лучше, как в большинстве соц.сетей - добавлять тэг(здесь категорию) вручную, не выбирая из списка возможных
Нашёл решение
def form_valid(self, form):
category_tokens = form.cleaned_data['categories'].split()
edit_categories = set()
for token in category_tokens:
try:
category = Category.objects.get(name=token)
except Category.DoesNotExist:
category = Category.objects.create(name=token)
edit_categories.add(category)
categories = []
profile = self.request.user.profile
title = form.cleaned_data.get('title')
body = form.cleaned_data.get('body')
image = form.cleaned_data.get('image')
for category_to_add in edit_categories:
categories.append(Category.objects.get_or_create(name=category_to_add.name)[0])
Post.objects.filter(pk=self.object.pk).delete()
instance = Post.objects.create(title=title, body=body, profile=profile, image=image)
instance.categories.set(categories)