Django - 在基于 Class 的 ListView 中克隆模型对象

Django - Clone model object in Class based ListView

我有一个包含大量记录的 list.html 和一个包含用于克隆特定记录的按钮的列,如下所示:

{% for betr in object_list %}
    ....
    <td>
        <button type="button" class="btn btn-first" onclick="window.location='../clone/{{betr.ID}}';">
            <span class="fas fa-copy" style="font-size: 1rem;"></span>
        </button>
    </td>
{% endfor %}

我的 urls.py 看起来像这样:

urlpatterns = [
...
path('update/<int:pk>/', UpdateView.as_view(), name='update'),
path('clone/<int:pk>/', CloneView.cloneRecord(), name='clone'),
...
]

我的 views.py 包含一个克隆视图,该视图具有克隆记录和打开 UpdateView 以及克隆记录进行编辑的功能:

class CloneView(LoginRequiredMixin):
    login_url = '/accounts/login/'
    model = mymodel
    def cloneRecord(self,**kwargs):
        record = mymodel.objects.filter(id=self.request.GET['ID'])[0]
        record.id = None
        record.save()
        return http.HttpResponseRedirect(reverse('/update/', kwargs={'pk':record.id}))

目前我收到以下错误:

TypeError: cloneRecord() missing 1 required positional argument: 'self'

我错过了什么?感谢任何帮助。

删除括号,CloneView.cloneRecord()

path('clone/<int:pk>/', CloneView.cloneRecord, name='clone'),

如果两个视图都有单独的 url,那么您应该在 GET 方法中编写代码,如下所示

class CloneView(LoginRequiredMixin, View):
    login_url = '/accounts/login/'

    def get(self,**kwargs):
        record = mymodel.objects.filter(id=self.request.GET['ID'])[0]
        record.id = None
        record.save()
        return http.HttpResponseRedirect(reverse('/update/', kwargs={'pk':record.id}))

你的url应该是这样的

path('clone/<int:pk>/', CloneView.as_view(), name='clone'),

请记住,as_view 用于调用基于 class 的视图。您不能根据调用的函数进行更改。

这是克隆对象的另一种变体。最大的优势是您打开所需的 CreateView,然后它会填充您从中获得 ID 的对象,然后您可以根据需要保存它。不要忘记在模型中实施一些唯一约束以避免重复记录! 在这种情况下,您不会处于用户正在生成无用的重复记录的情况,因为只有当用户真正使用 AssemblyCloneView 中的提交按钮保存它时,它才会被保存!

urls.py:

urlpatterns = [
...
path('assembly/clone/<int:pk>/', AssemblyCloneView.as_view(), name='assembly_clone'),

template.html:(在我的例子中使用 bootstrap 按钮)

<a class="btn btn-light btn-sm" href="{% url 'engineering:assembly_clone' record.id %}">Clone</a>

views.py:

class AssemblyCloneView(LoginRequiredMixin, CreateView):
    model = Assembly

    """
    Get object desired from url with record.id and override the object context with it.
    """
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        context = self.get_context_data(object=self.object)
        print(context)
        return self.render_to_response(context)

    def get_success_url(self):
        return reverse_lazy('engineering:assembly_detail', kwargs={'pk': self.object.pk})