5

我在 django 中编写了一个简单的反馈应用程序。它并不特别复杂,基本上它允许经过身份验证的用户编写带有主题行的快照消息并通过表单提交该消息。然后,我允许选定组中的人员查看用户提交的反馈。将来我可能会添加更多功能,但现在它可以满足我的需求。

我的问题来了,我正在构建的网站有多个我想使用反馈应用程序的地方,例如我有一个“你觉得这个网站怎么样?” 我在“/support/feedback/”上也有一个用于客户支持反馈的页面。/dev/feedback/目前我刚刚将代码从我复制mysite.apps.dev.feedbackmysite.apps.support.feedback.

问题是这现在已经创建了相同代码的两个单独的副本。尽管刚刚编写了应用程序,但两个版本已经开始出现分歧,这很烦人。我的问题只是如何在具有不同数据库模型的 django 站点中创建同一应用程序的多个实例?

我发现一些相关但没有帮助的资源是https://docs.djangoproject.com/en/dev/topics/http/urls/Reversing namespaced URLs in Django: multiple instances of the same app The first page does not offer关于这个问题的内容很多,第二页提供了一些笨拙和不切实际的解决方案,这些解决方案似乎既不相关,而且工作量超过其价值。有没有一种正确的方法来实现同一个 django 应用程序的多个实例?

4

3 回答 3

3

单一模型方法

我个人会尝试将其保留为一个应用程序,并拥有一个可以处理从多个位置发布/适当标记它们的视图。

正如 S.Lott 所说,这是要走的路。如果您对在其他情况下将代码保留在一个地方的方法感到好奇,我将提供替代方案。

例如,您可以category在模型中添加一个字段,设置一个接受 URL 中的参数的单个 url conf,/(?P<category>\w+/feedback/$并让视图简单地用适当的类别标记反馈。

class MyForm(forms.ModelForm):
    class Meta:
        model = Feedback

def my_view(request, category):
    form = MyForm(request.POST or None)
    if request.method == 'POST':
        if form.is_valid():
            feedback = form.save(commit=False)
            feedback.category = category
            feedback.save()
            return http.HttpResponse("Thanks for posting!")
    return render(request, "mytemplate.html", {'form': form})

# urls.py
(r'^(?P<category>\w+)/feedback/$', 'my_view')

# user can visit dev/feedback or support/feedback and the feedback will be tagged appropriately

抽象基类

另一种解决方案是构建一个抽象基类,然后为不同的表创建子类。这应该可以解决您的代码不同步的问题。

您将拥有一个抽象模型(没有表),您的单独应用程序中的“真实”模型将基于该模型。

动态生成的视图

如果您必须有单独的模型,您可能会编写一个动态构造的视图。

def view_generator(model_class):
    class MyForm(forms.ModelForm):
         class Meta:
              model = model_class

    def my_view(request):
        form = MyForm(request.POST or None)
        if request.method == 'POST':
            if form.is_valid():
                form.save()
                return http.HttpResponse("Thanks for posting!")
        return render(request, "mytemplate.html", {'form': form})
    return my_view


# urls.py
from foo import view_generator

(r'^my_first_feedback_form', view_generator(Model1))
(r'^my_second_feedback_form', view_generator(Model2l))
于 2012-01-14T01:29:54.137 回答
2

如何在具有不同数据库模型的 django 站点中创建同一应用程序的多个实例?

你不应该。

您只需在其他两个应用程序中使用反馈应用程序模型,并使用一个简单的 from feedback.models import Feedback.

然后您的support应用程序可以创建、检索、更新和删除反馈对象。

同样,您的dev应用程序可以创建、检索、更新和删除反馈对象,因为它导入了模型。

这就是所有需要的:import.

于 2012-01-14T01:32:57.093 回答
1

感谢 Yuji Tomita 提供了非常彻底的回答,我的最终解决方案非常接近他的建议,但差异很大,以至于我认为如果其他人遇到与我相同的情况,我会将其作为另一种选择发布。

首先在我的mysite.apps.feedback.models文件中我放

class Feedback( models.Model ):
   subject = models.TextField( max_length=100 )
   body = models.TextField( max_length=100 )
   # Some other stuff here...
   # Finally I used the suggestion above and created a field which I 
   # use to label each entry as belonging to a specific instance of the app.
   instance_name = models.TextField( max_length=20 )

在我的mysite.apps.feedback.views文件中,我放了

def save_message( request, instance_name ):
    if request.method == 'POST':
        form = FeedbackFrom( request.POST )
        if form.is_valid():
            form.instance.instance_name = instance_name
            form.save()
            return render("feedback/thanks.html")
         else:
             return render("feedback/submit.html", {'form':form })
     else:
         return render("feedback/submit.html",{'form':FeedbackForm()})

@user_passes_test( is_staff )
def all_messages( request, instance_name ):
    messages = Feedback.objects.filter( instance_name = instance_name )
    return render("feedback/view_all.html",{'feedback':messages} )

在我的mysite.apps.dev.urls文件中,我放了

url(r'^feedback/', include('mysite.apps.feedback.urls'),
    {'instance_name':'dev'}),

在我的mysite.apps.support.urls文件中,我放了

url(r'^feedback/', include('mysite.apps.feedback.urls'),
    {'instance_name':'support'}),

这将按应用实例分隔反馈消息。请注意,我的实际代码更复杂,但这应该足以让任何有类似问题的人快速启动并运行解决方案。希望这对处于类似情况的任何人都有用。再次感谢 Yuji Tomita 提供此解决方案所依据的建议。

于 2012-01-15T20:05:20.020 回答