Django CRUD更新对象与用户具有多对一的关系 [英] Django CRUD update object with many to one relationship to user

查看:141
本文介绍了Django CRUD更新对象与用户具有多对一的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我沿着令人敬畏的教程如何使用Ajax和Json实现CRUD?Vitor Freitas。对于我的项目,我有一个与用户有很多关系的对象,我希望用户能够添加和更新。我可以添加对象,但是当我尝试更新它会抛出
ValueError:无法查询Case对象:必须是User实例。



views.py

  def case_update请求,pk):
case = get_object_or_404(Case,pk = pk)
如果request.method =='POST':
form = CaseForm(request.POST,instance = case)
else:
form = CaseForm(instance = case)
return save_case_form(request,form,'cases / includes / partial_case_update.html')
/ pre>

当我尝试保存编辑时,它会中断,但我很难想到这一点。要编辑这种情况,我需要表单作为这种特定情况的一个实例,因为用户可能有很多情况。当我将实例设置给用户时,没有任何反应,当我完全删除实例时,显然只是复制一个案例,所以我有两个相同的情况。



如果需要,我可以发布更多的代码。谢谢



编辑
我只使用inlineformset重构了我的代码,它正在工作...。我现在可以编辑案例,但我仍然无法编辑单个案例。我继续收到一个 ValueError:无法查询Case对象:当我尝试执行 case = get_object_or_404的一个实例时,必须是User实例 (Case,pk = pk)与inlineformset。当我将其更改为用户的实例时,它会显示该特定用户的所有情况,但会正确保存。

  def save_case_form(request,case_formset,template_name):
data = dict()

如果request.method =='POST':
如果case_formset.is_valid():
case_formset.save()
data ['form_is_valid'] = True
cases = Case .objects.all()
data ['html_case_list'] = render_to_string('cases / includes / partial_case_list.html',{
'cases':cases
})
else :
data ['form_is_valid'] = False
context = {'case_formset':case_formset}
data ['html_form'] = render_to_string(template_name,context,request = request)
返回JsonResponse(数据)


def case_create(request):
如果request.method =='POST':
case_formset = CaseFormset(request.POST, instance = request.user)
else:
case_formset = CaseFormset()
return save_case_for (请求,case_formset,'cases / includes / partial_case_create.html')


def case_update(request,pk):
case = get_object_or_404(Case,pk = pk)
如果request.method =='POST':
case_formset = CaseFormset(request.POST,instance = request.user)
else:
case_formset = CaseFormset(instance = request。用户)
return save_case_form(request,case_formset,'cases / includes / partial_case_update.html')

forms.py

  class CaseForm(forms.ModelForm):
class Meta :
model = Case
fields =('title','publication_date','author','price','pages','case_type')


CaseFormset = inlineformset_factory(User,Case,
fields =('title','publication_date',
'author','price',
'pages','case_type'),
can_delete = False,
extra = 1)

编辑



非DRY实现工作:



forms.py

  class CaseForm(forms.ModelForm):
class Meta:
model = Case
fields =('title','publication_date','author','price','pages','case_type')


CaseFormset = inlineformset_factory(User,Case,
fields =('title','publication_date',
'author','price',
'pages','case_type',),
can_delete = False,
extra = 1)

CaseFormsetUpdate = inlineformset_factory(User,Case,
fields =('title','publication_date',
'author','price',
'pages','case_type' ),
can_delete = False,
extra = 0)

view.py

  def save_case_form(request,case_formset,template_name):
data = dict

如果request.method =='POST':
如果case_formset.is_valid():
case_formset.save()
data ['form_is_valid'] = True
cases = Case.objects.all()
data ['html_case_list'] = render_to_string('cases / includes / partial_case_list.html',{
'cases':cases
})
其他:
data ['form_is_valid'] = False
context = {'case_formset':case_formset}
data ['html_form'] = render_to_string(template_name,context,request = request)
返回JsonResponse(data)


def case_create(request):

如果request.method =='POST':
case_formset = CaseFormset .pOST,instance = request.user)
else:
case_formset = CaseFormset()
return save_case_form(request,case_formset,'cases / includes / partial_case_create.html')


def case_update(request,pk):

case = get_object_or_404(Case,pk = pk)
如果request.method =='POST':
case_formset = CaseFormsetUpdate(request.POST,instance = request.user)
else:
case_formset = CaseFormsetUpdate(instance = request.user,queryset = Case.objects.filter(pk = pk))
return save_case_form(request,case_formset,'cases / includes / partial_case_update .html')

我无法找到一种在内联表单中更改额外参数的方法它在视图中实例化。所以我只是做了第二个额外设置为0,并将其添加到我的更新案例视图。我仍然会对一个更好的方法感兴趣。

解决方案

经过大量的尝试和错误,我找到了一个解决方案。我一直在使用内联表单,因为我一直在找到指出这个方向的答案,但是如果可能的话我宁愿手动执行,而且我一直在努力,但是我在这方面做的这件事情在某种原因上没有起作用。



我一直在尝试如下:

  case = form。保存(commit = False)
case.user = request.user

  form =(request.POST,instance = request.user)
form.save()

我发现这个解决方案,它现在可以像没有内联格式一样工作。

  form.instance.user = request.user 
form.save()

几乎相当于我一直在做的,但它的工作。


I followed along the awesome tutorial How to Implement CRUD Using Ajax and Json by Vitor Freitas. For my project I have an object with a many to one relationship with the user that I want users to be able to add and update. I can add the object, but when I try to update it throws a ValueError: Cannot query "Case object": Must be "User" instance.

views.py

def case_update(request, pk):
    case = get_object_or_404(Case, pk=pk)
    if request.method == 'POST':
        form = CaseForm(request.POST, instance=case)
    else:
        form = CaseForm(instance=case)
    return save_case_form(request, form, 'cases/includes/partial_case_update.html')

It breaks when I try to save the edit, but I am struggling to see a way around this. To edit this case, I need the form to be an instance of this particular case as the user may have many cases. When I set the instance to user, nothing happens, when I remove the instance altogether it obviously just makes a copy of the case so I have two of the same cases.

I can post more code if necessary. Thank you

EDIT I refactored my code using only the inlineformset and it is working... kind of. I now can edit cases, but I still cannot edit a single case. I continue to receive a ValueError: Cannot query "Case object": Must be "User" instance when I try to do an instance of case = get_object_or_404(Case, pk=pk)with the inlineformset. When I change this to an instance of user it brings up all the cases of that particular user, but it saves correctly.

def save_case_form(request, case_formset, template_name):
    data = dict()

    if request.method == 'POST':
        if case_formset.is_valid():
            case_formset.save()
            data['form_is_valid'] = True
            cases = Case.objects.all()
            data['html_case_list'] = render_to_string('cases/includes/partial_case_list.html', {
                'cases': cases
            })
        else:
            data['form_is_valid'] = False
    context = {'case_formset' : case_formset}
    data['html_form'] = render_to_string(template_name, context, request=request)
    return JsonResponse(data)


def case_create(request):
    if request.method == 'POST':
        case_formset = CaseFormset(request.POST, instance = request.user)
    else:
        case_formset = CaseFormset()
    return save_case_form(request, case_formset, 'cases/includes/partial_case_create.html')


def case_update(request, pk):
    case = get_object_or_404(Case, pk=pk)
    if request.method == 'POST':
        case_formset = CaseFormset(request.POST, instance=request.user)
    else:
        case_formset = CaseFormset(instance=request.user)
    return save_case_form(request, case_formset, 'cases/includes/partial_case_update.html')

forms.py

class CaseForm(forms.ModelForm):
    class Meta:
        model = Case
        fields = ('title', 'publication_date', 'author', 'price', 'pages', 'case_type', )


CaseFormset = inlineformset_factory(User,Case, 
                                    fields = ('title', 'publication_date', 
                                              'author', 'price', 
                                              'pages', 'case_type', ), 
                                    can_delete = False,
                                    extra = 1)

EDIT

A non DRY implementation that works:

forms.py

class CaseForm(forms.ModelForm):
    class Meta:
        model = Case
        fields = ('title', 'publication_date', 'author', 'price', 'pages', 'case_type', )


CaseFormset = inlineformset_factory(User,Case, 
                                    fields = ('title', 'publication_date', 
                                              'author', 'price', 
                                              'pages', 'case_type', ), 
                                    can_delete = False,
                                    extra = 1)

CaseFormsetUpdate = inlineformset_factory(User,Case, 
                                    fields = ('title', 'publication_date', 
                                              'author', 'price', 
                                              'pages', 'case_type', ), 
                                    can_delete = False,
                                    extra = 0)

views.py

def save_case_form(request, case_formset, template_name):
    data = dict()

    if request.method == 'POST':
        if case_formset.is_valid():
            case_formset.save()
            data['form_is_valid'] = True
            cases = Case.objects.all()
            data['html_case_list'] = render_to_string('cases/includes/partial_case_list.html', {
                'cases': cases
            })
        else:
            data['form_is_valid'] = False
    context = {'case_formset' : case_formset}
    data['html_form'] = render_to_string(template_name, context, request=request)
    return JsonResponse(data)


def case_create(request):

    if request.method == 'POST':
        case_formset = CaseFormset(request.POST, instance = request.user)
    else:
        case_formset = CaseFormset()
    return save_case_form(request, case_formset, 'cases/includes/partial_case_create.html')


def case_update(request, pk):

    case = get_object_or_404(Case, pk=pk)
    if request.method == 'POST':
        case_formset = CaseFormsetUpdate(request.POST, instance=request.user)
    else:
        case_formset = CaseFormsetUpdate(instance=request.user, queryset = Case.objects.filter(pk=pk))
    return save_case_form(request, case_formset, 'cases/includes/partial_case_update.html')

I was unable to find a way to change the extra parameter on an inline formset when it is instantiated in views. So I just made a second one with extra set to 0 and added that to my update case view. I would still be interested in a better approach.

解决方案

After a lot of trial and error I found a solution. I had been using inline formsets because I kept finding answers that pointed that direction, but I would rather do it manually if possible and I had been trying, but how I had been doing this did not work in this instance for some reason.

I had been trying something like:

case = form.save(commit = False)
case.user = request.user

or

form = (request.POST, instance = request.user)
form.save()

I came across this solution and it now works as intended without inline formsets.

form.instance.user = request.user
form.save()

This looks almost equivalent to what I had been doing, but it worked.

这篇关于Django CRUD更新对象与用户具有多对一的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆