【问题标题】:How do I use an UpdateView to update a Django Model?如何使用 UpdateView 更新 Django 模型?
【发布时间】:2012-03-05 12:26:09
【问题描述】:

我正在尝试使用基于类的通用视图 UpdateView 更新 Django 中的模型。

我阅读了页面 Updating User model in Django with class based UpdateView 以尝试让我开始,但我收到一个错误 'WSGIRequest' object has no attribute 'id'

我是 Django 的新面孔,所以如果我做了一些愚蠢的事情,请原谅。

//urls.py

url(r'^portfolios/update/(?P<id>\d+)/$',PortfoliosUpdateView.as_view()),

//views.py

class PortfoliosUpdateView(UpdateView):
    form_class = PortfoliosCreateForm
    model = Portfolios
    template_name = 'portfolios/create.html'

    def get(self, request, **kwargs):
        self.object = Portfolios.objects.get(id=self.request.id)
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        context = self.get_context_data(object=self.object, form=form)
        return self.render_to_response(context)

    def get_object(self, queryset=None):
        obj = Portfolios.objects.get(id=self.request.id)
        return obj

这主要是最初发布的代码的修改版本,但我认为它可以工作。我知道我正在尝试检索作为 GET 参数传递的 id,但这似乎并没有出现在请求变量中。我是不是走错了路?

谢谢

编辑:我想我已修复它,但这可能是错误的: 我换了台词

self.object = Portfolios.objects.get(id=self.request.id)
obj = Portfolios.objects.get(id=self.request.id)

到

self.object = Portfolios.objects.get(id=self.kwargs['id'])
obj = Portfolios.objects.get(id=self.kwargs['id'])

我可能错了。

【问题讨论】:

  • 您的更新确实正确修复了原始错误。我不明白为什么你需要重写 get 方法,看起来这就是 UpdateView 在幕后所做的。

标签: django view


【解决方案1】:

应该是:

def get_object(self, queryset=None):
    obj = Portfolios.objects.get(id=self.kwargs['id'])
    return obj

查看基于类的通用视图调度说明关键字参数分配给 self.kwargs。:

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    self.request = request
    self.args = args
    self.kwargs = kwargs
    return handler(request, *args, **kwargs)

【讨论】:

  • 感谢您的澄清。我已经大大简化了我的代码。
【解决方案2】:

id = self.request.GET.get('id',None) 是您在尝试访问 GET 查询字符串时所需要的。

但是,您的视图可以简化:

from django.conf.urls import *
from django.views.generic import UpdateView
from yourapp.models import Portfolios
from yourapp.forms import PortfoliosCreateForm

urlpatterns = patterns('',
    url('^portfolios/update/(?P<pk>[\w-]+)$', UpdateView.as_view(
        model=Portfolios,
        form_class=PortfoliosCreateForm,
        template_name='portfolios/create.html',
        success_url='/portfolios'
    ), name='portfolio_update'),
)

【讨论】:

  • 我更喜欢将我的观点包含在 myapp.views 中。例如。在myapp.views:portfolio_update = UpdateView.as_view(...),然后在urlconf中我只需要输入url(r'pattern', "myapp.views.portfolio_update", name="portfolio_update")。不适合所有目的,但我发现它对我的大多数观点来说更干净。
  • 虽然这是一个完全有效的解决方案,但最好的 Django 实践建议为 views.py 保留该逻辑,而不是在 url 模式中。 -- 来自 Django 的两勺
  • 我贴的sn-p里面没有逻辑。 @JacobValenta
  • 我的意思是模型中的逻辑,form_class,template_name 和成功 url,CBV 就是这样,基于类的视图,实现它们的最佳方法(来自 Django 的两个勺子)是 .as_view( )
  • @BurhanKhalid 正则表达式不应该是 (?P&lt;pk&gt;\d+)/$。你的正则表达式也会匹配一个 slug
【解决方案3】:

views.py

class MyUpdateView(UpdateView):
    model = ModelName  # required
    template_name = 'x/h1.html'
    form_class = ModelNameForm
    success_url = reverse_lazy('app:page1')

    def get_queryset(self):
        """
        Optional condition to restrict what users can see
        """
        queryset = super().get_queryset()
        return queryset.filter(id__lt=20)

    def get_success_url(self):
        return reverse_lazy(
            'app1:abc',
            kwargs={'pk': self.object.id}
        )

urls.py

在urlpatterns=[]

path('xyz/<pk>/', MyUpdateView.as_view(),name='xyz')

my_model_view.html

{{form}}

您将能够在 url /xyz/&lt;pk&gt;/ 处编辑 ModelName,其中 &lt;pk&gt; 可以是 1 到 20 之间的任何值,具体取决于我们在 get_queryset() 中的条件。取消该条件以允许用户编辑任何对象。

self.object 仅在向 UpdateView 发布请求后可用。

【讨论】:

    猜你喜欢
    • 2011-09-05
    • 2015-01-13
    • 2021-06-17
    • 2020-04-24
    • 2014-10-14
    • 2015-07-29
    • 1970-01-01
    • 2021-05-29
    • 2020-04-15
    相关资源
    最近更新 更多