Django ModelForm保存和获取〈QuerySet对象>而不是值

zujrkrfu  于 2022-12-24  发布在  Go
关注(0)|答案(2)|浏览(133)

我有一个简单的Django 3.1.0应用程序,我需要创建,以分配任务与标签(或分配标签到任务)。

    • 型号**
class Task(models.Model):

    user = models.CharField(max_length=33)
    time = models.DateTimeField(auto_now_add=True)
    task = models.CharField(max_length=500)
    tags = models.CharField(max_length=100, default="None", null=True)

class Tag(models.Model):

    tag = models.CharField(max_length=30, default="No Tag")
    members = models.ManyToManyField('Task', related_name="tag")

    class Meta:
        verbose_name = "tag"
        verbose_name_plural = "tags"
    • 查看**
def main(request):
    model = Task.objects.values().all()
    tags = Tag.objects.values().all()
    form = TaskForm()
    con = {'context': list(model), 'form': form, 'tags': list(tags)}
    if request.method == 'POST':
      form = TaskForm(request.POST)
      if form.is_valid():
          form.save()
          return redirect('/')
    else:
        form = TaskForm()
    return render(request, "tasks.html", con)
    • 表格**
class TaskForm(ModelForm):
    class Meta:
        model = Task
        fields = ['user', 'task', 'tags']
        template_name = 'tasks.html'

    tags = ModelMultipleChoiceField(
    queryset= Tag.objects.all(),
    widget=CheckboxSelectMultiple(), required=False,
    )
    • 任务表单**
<form method="post" class="form">
    {% csrf_token %}
    {{form}}
    <input type="submit" value="Save">
</form>

这将在标记列表中返回如下所列的项目:

  • 标签对象(1)
  • 标签对象(2)

当我按提交键保存时,它会取一个表(在另一个模板中),保存在<QuerySet [<Tag: Tag object (2)>]>文本中的值,这就是它在数据库中存储它们的方式。
我已经成功地提取了这些值('jenkins','AKS'),并使用以下命令在模板中发送它们(bootstrapvuejs):{% for tag in tags %}<b-form-checkbox>{{tag.tag}}</b-form-checkbox>{% endfor %},它完美地列出了原始值。
但是,当我进行修改时,提交的表单没有写入数据库。
我错过了什么?

    • UPDATE!**通过将以下内容添加到Tag模型中,我已经部分解决了这个问题:
def __str__(self):
        return self.tag

但是当它在提交时持久化它时,它仍然将其保存为:<QuerySet [<Tag: jenkins>]>
那么,如何以及在何处只剥离要插入数据库的特定标记值呢?
多谢

gab6jxml

gab6jxml1#

好了,你的代码有几个问题,首先是你的主视图
将其更改为:

def main(request):
    model = Task.objects.values().all() # calling values without specifying an argument makes no sense so just call it like **Task.objects.all()**
    tags = Tag.objects.values().all() # same here
    form = TaskForm() # don't call your form here it gets reassigned later anyways
    con = {'context': list(model), 'form': form, 'tags': list(tags)} # don't define your context here since you are reasigning your form later so the form instance is always TaskForm()

    if request.method == 'POST':
        form = TaskForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')
        else:
            form = TaskForm()

    return render(request, "tasks.html", con)

对此:

def main(request):
    model = Task.objects.all()
    tags = Tag.objects.all()

    if request.method == 'POST':
      form = TaskForm(request.POST)
      if form.is_valid():
          form.save()
          return redirect('/')
    else:
        form = TaskForm()

    context = {'tasks': model, 
               'form': form, 
               'tags': tags}

    return render(request, "tasks.html", con)

然后在模板中使用as_p方法调用传递表单:

{{ form.as_p }}

然而,您得到的错误不是因为您的html或您的视图,而是因为您的Task模型中的tags字段与您的Tag模型之间没有ManyToMany关系,而是一个简单的CharacterField,并且您试图将objects保存到CharField,因此请按如下所示重写您的Task模型:

class Task(models.Model):
    user = models.CharField(max_length=33)
    time = models.DateTimeField(auto_now_add=True)
    task = models.CharField(max_length=500)
    tags = models.ManyToMany(Tags)

然后表单应该将它们保存在Task示例的tags字段中,您可以如下所示查看它们:

task = Task.objects.get(pk=1)
task_tags = task.tags.all() # stores a queryset of all tags of the queried task

模板中:

{% for tag in task.tags.all %}
...
{% endfor %}
cdmah0mi

cdmah0mi2#

好的,我解决了保存在数据库中作为Queryset的POST数据,通过在调用save()的视图中提取,字段'tags'同样:

f = form.save(commit=False)
          f.tags = request.POST['tags']
          form.save()

现在唯一的问题是表单中有多个复选框,但这样它只提取其中一个,而我希望它返回一个类似于request.POST中打印的列表:<QueryDict: {'csrfmiddlewaretoken': ['XV7HgTFiWXEnrkhqT3IsqUN2JbnT7YIH5r6fKgh2ehqeLsLMpvCPdUU4N2qwWuPk'], 'user': ['afa'], 'task': ['aff'], 'tags': ['jenkins', 'AKS']}>-〉从中我称之为“标签”,但它只保存了“Jenkins"...

***UPDATE***OK,我RTFM并看到QueryDict对象上有一个方法可以传递给request.POST.getlist('tags'),所以现在它返回'tags'键的完整值。

相关问题