【问题标题】:Django update boolean field with a formDjango 使用表单更新布尔字段
【发布时间】:2021-03-03 13:33:07
【问题描述】:

我的简单网络应用程序有两个链接的模型(一对多)。

第一个模型 (Newplate) 有一个名为 plate_complete 的布尔字段。这在开始时设置为False (0)。

问题:

  1. 在一个 html 页面中,我正在尝试构建一个表单和按钮,按下该按钮会将上述字段设置为 True。在我单击按钮时,页面刷新但数据库没有变化(plate_complete 仍然是False)。我该怎么做?

  2. 理想情况下,一旦按下按钮,我还想将用户重定向到另一个网页 (readplates.html)。此网页不需要 pk 字段(但表单确实可以更改特定记录)因此现在我只是刷新extendingplates.html 文件。我该怎么做呢?

我的代码:

"""Model"""
class NewPlate(models.Model):
    plate_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=200)
    created_date = models.DateTimeField(default=timezone.now)
    plate_complete = models.BooleanField()

"""view"""
def publish_plates(request,plate_id):
    newplate = get_object_or_404(NewPlate, pk=plate_id)
    newplate.plate_complete = True
    newplate.save()

    #2nd method
    NewPlate.objects.filter(pk=plate_id).update(plate_complete = True)

    return HttpResponseRedirect(reverse('tablet:extendplates', args=[plate_id]))




"""URLS"""
       path('readplates', views.read_plates, name='readplates'),
       path('extendplates/<pk>/', views.show_plates, name='showplates'),
       path('extendplates/<pk>/', views.publish_plates, name='publishplates'),

"""HTML"""
    <form method="POST" action="{% url 'tablet:publishplates' newplate.plate_id %}">
    {% csrf_token %}
    <button type="submit" class="button" value='True'>Publish</button></form>   

-------Added show plates view:---------

def show_plates(request,pk):
    mod = NewPlate.objects.all()
    newplate= get_object_or_404(mod, pk=pk)
    add2plate= Add2Plate.objects.filter(Add2Plateid=pk)
    return render(request, 'tablet/show_plates.html', {'newplate': newplate,'add2plate': add2plate})





谢谢

【问题讨论】:

    标签: django forms


    【解决方案1】:

    问题是您的两个网址具有相同的模式'extendplates/&lt;pk&gt;/'。 Django 使用第一个匹配 url 的模式。我想其中一个视图views.show_plates 用于显示表单,另一个views.publish_plates 用于接受发布的表单数据。

    这意味着这两个视图都应该只是一个单个视图(为了区分是否提交了表单,我们将简单地检查 requests 方法):

    from django.shortcuts import redirect, render
    
    
    def show_plates(request, plate_id):
        newplate = get_object_or_404(NewPlate, pk=plate_id)
        if request.method == "POST":
            newplate.plate_complete = True
            newplate.save()
            return redirect('tablet:extendplates', plate_id)
        context = {'newplate': newplate}
        return render(request, 'your_template_name.html', context)
    

    现在您的 url 模式可以很简单(注意:捕获的参数也作为关键字参数传递给视图,因此它们应该与您的视图和模式保持一致):

    urlpatterns = [
        ...
        path('readplates', views.read_plates, name='readplates'),
        path('extendplates/<uuid:plate_id>/', views.show_plates, name='showplates'),
        ...
    ]
    

    在您的表单中,只需放弃同一页面上的 action 属性即可:

    <form method="POST">
        {% csrf_token %}
        <button type="submit" class="button" value='True'>Publish</button>
    </form>
    

    【讨论】:

    • 是的!这非常有帮助,谢谢。我一直在追寻自己的尾巴,我现在正在讨论这个问题,但我认为你已经解决了这个问题。稍后会发送更新。
    【解决方案2】:

    您应该避免像当前视图那样更改获取请求的状态。

    处理POST请求并在请求有效时更改数据(确保CSRF保护)。

    def publish_plates(request,plate_id):
        newplate = get_object_or_404(NewPlate, pk=plate_id)
    
        if request.method == "POST":
            newplate.plate_complete = True
            newplate.save(update_fields=['plate_complete'])  # a more efficient save
    
            #2nd method
            NewPlate.objects.filter(pk=plate_id).update(plate_complete=True)
    
        return HttpResponseRedirect(reverse('tablet:extendplates', args=[plate_id]))
    

    您还可以在表单中放置一个隐藏输入,或者在 Django 中创建一个表单来保存隐藏输入,它存储 plate_id 值,这样您就可以拥有一个通用 URL,该 URL 将从 @ 获取该 ID 987654324@数据。

    现在你遇到的真正问题是,你有 2 个相同的 URL,但有 2 个不同的视图。

    我建议您更改它,以便 URL 是唯一的;

           path('extendplates/<pk>/', views.show_plates, name='showplates'),
           path('publish-plates/<pk>/', views.publish_plates, name='publishplates'),
    

    【讨论】:

    • 感谢您的回答。所以我知道 URL 应该是唯一的,我会改变它。我真正想做的是单击“表单按钮”,布尔字段更改为 true,并将我重定向到另一个页面。
    • @JackGowan 您也可以使用update_fields kwarg on save 来提高效率,因为您只是更改了 1 个字段。
    猜你喜欢
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    相关资源
    最近更新 更多