【问题标题】:I have a table in Django with ManyToManyField. Can't figure out how to update a table entry我在 Django 中有一张带有 ManyToManyField 的表。无法弄清楚如何更新表条目
【发布时间】:2021-08-31 03:09:36
【问题描述】:

我有一个包含多个类别的帖子的表格,以及一个包含多个帖子的类别的表格。模型.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

Сlass 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')

我不知道如何更新帖子,以便也更新类别。 我寻找了许多解决方案,但没有一个有帮助。 我尝试了 get_or_create、更新、删除,然后再次创建,但没有任何效果。 更好,就像在大多数社交网络中一样 - 手动添加标签(这里是一个类别),而不是从可能的列表中选择

【问题讨论】:

  • 嗨,Steep27!你到底想更新什么? Category 和 Post 的关系,单个 Post 或 Category 的数据?你努力的结果应该是什么?
  • 您好,我想更新分类。我有一个用于创建和编辑帖子的表单,但是当我在编辑页面上时,当我在类别栏中输入任何类别(例如“任何”)时,会出现错误“字段 'id' 需要一个数字但有一个'”。字段“名称”、“正文”、“图像”正常更新,但字段“类别”有问题。
  • 你能发布你的PostDocumentForm吗?
  • 更新问题,添加 forms.py
  • 您需要为您的类别使用ModelMultipleChoiceField 而不是CharField。 Django 通过此表单处理更新并尝试使用您的字符串内容更新类别 - 这将不起作用。看这里:docs.djangoproject.com/en/3.2/ref/forms/fields/…

标签: python django django-models django-views many-to-many


【解决方案1】:

这可能会对您有所帮助:

class PostEditView(UpdateView):
     def form_valid(self, form):
        # Take care of creating of updating your post with cleaned data
        # by yourself

        category_tokens = form.cleaned_data['categories'].split()
        categories = set()
        for token in category_tokens:
            try:
                category = Category.objects.get(name=token)
            except ObjectDoesNotExist:
                category = Category.objects.create(name=token)
            
            categories.add(category)

        # now you need to add the categories which are new to this post
        # and delete the categories which do not belong anymore to your post
        current_posts_categories = set(post_instance.categories_set.all())
        categories_to_add = categories - current_posts_categories
        categories_to_delete = current_posts_categories - categories

        # further handling is up to you ...

【讨论】:

    猜你喜欢
    • 2016-07-05
    • 2014-02-27
    • 2013-11-05
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 2016-02-26
    相关资源
    最近更新 更多