简体   繁体   English

django应用程序的多个实例,django是否支持此功能

[英]Multiple Instances of a django app, does django support this

I have written a simple feedback application in django. 我已经在Django中编写了一个简单的反馈应用程序。 It's not particulairly complex, basically it allows authenticated users to write a shot message with a subject line and submit that message via a form. 它并不是特别复杂,基本上,它允许经过身份验证的用户编写带有主题行的快照消息,并通过表单提交该消息。 I then allows who are in a selected group to view user submitted feedback. 然后,我允许选定组中的谁查看用户提交的反馈。 In the future I may add more functionality but for now it does what I want. 将来我可能会添加更多功能,但是现在它可以满足我的要求。

Here comes my question, the site I'm building has multiple places where I would like to use the feedback app, for example I have a "what do you think of the site?" 我的问题来了,我正在建设的网站有多个我想使用反馈应用程序的地方,例如,我有一个“您如何看待该网站?” kind of page at /dev/feedback/ I also have one for customer support feedback at "/support/feedback/" Currently I have just copied the code from my mysite.apps.dev.feedback over to mysite.apps.support.feedback . /dev/feedback/此类页面。“ / support / feedback /”上也有一个客户支持反馈的页面。目前,我刚刚将代码从mysite.apps.dev.feedback复制到mysite.apps.support.feedback

The problem is that this has now created two separate copies of the same code. 问题在于,这现在已经创建了同一代码的两个单独的副本。 Despite having just written the app the two versions are already starting to diverge which is annoying. 尽管刚刚编写了该应用程序,但这两个版本已经开始出现差异,这很烦人。 My question is simply how do I create multiple instances of the same app in a django site with distinct database models? 我的问题只是简单地如何在具有不同数据库模型的Django站点中创建同一应用程序的多个实例?

Some resources I've found related but not helpful are https://docs.djangoproject.com/en/dev/topics/http/urls/ and Reversing namespaced URLs in Django: multiple instances of the same app The first page does not offer much on the issue and the second page provides somewhat cludgey and impractical solutions that seem to be both unrelated and more work than their worth. 我发现一些相关但无用的资源是https://docs.djangoproject.com/en/dev/topics/http/urls/Django中反向命名空间的URL:同一应用程序多个实例第一页没有提供在此问题上有很多内容,第二页提供了一些笨拙和不切实际的解决方案,这些解决方案似乎既无关紧要,又比其价值更大。 Is there a proper way to implement multiple instances of the same django app? 有没有适当的方法来实现同一Django应用程序的多个实例?

Single model approach 单模型方法

I'd personally try to keep this as one app and have a view that can handle being posted from multiple locations / tag them appropriately. 我个人试图将其保留为一个应用程序,并具有可以处理从多个位置发布/适当标记它们的视图。

As S.Lott says, this is the way to go . 正如S.Lott所说,这是要走的路 I am providing alternatives if you're curious about methods to keep your code in one place in other situations. 如果您对将代码保持在其他情况下的某个位置的方法感到好奇,我会提供其他选择。

For example, you could add a category field to your model, set up a single url conf which accepts an argument in the URL such as /(?P<category>\\w+/feedback/$ and have the view simply tag the feedback with the appropriate category. 例如,您可以在模型中添加一个category字段,设置一个URL conf,该URL接受URL中的参数,例如/(?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

Abstract base class 抽象基类

Another solution is to build an abstract base class , then create subclasses for your distinct tables. 另一个解决方案是构建一个抽象基类 ,然后为不同的表创建子类。 That should solve the issue with your code getting out of sync. 那应该解决您的代码不同步的问题。

You'd have a single abstract model (which has no tables) from which your "real" models in your separate apps would be based on. 您将有一个抽象模型(没有表),您的单独应用程序中的“真实”模型将基于该抽象模型。

Dynamically generated views 动态生成的视图

If you must have separate models, you could potentially write a dynamically constructed view. 如果必须具有单独的模型,则可以编写动态构造的视图。

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))

how do I create multiple instances of the same app in a django site with distinct database models? 如何在具有不同数据库模型的Django站点中创建同一应用程序的多个实例?

You shouldn't. 你不应该

You simply use the feedback app model in the other two apps with a simple from feedback.models import Feedback . 您只需在from feedback.models import Feedback一个from feedback.models import Feedback ,即可在其他两个app中简单使用feedback app模型。

Then your support app can create, retrieve, update and delete Feedback objects. 然后,您的support应用程序可以创建,检索,更新和删除反馈对象。

Your dev app, similarly, can create, retrieve, update and delete Feedback objects because it imported the model. 同样,您的dev应用程序可以导入模型,因此可以创建,检索,更新和删除“反馈”对象。

That's all that's required: import . 这就是所有需要的内容: import

Thanks Yuji Tomita for a very thorough answer, my final solution is derived very closely from his suggestion, but is different enough that I thought I would post it as another option if someone else runs into the same situation that I am in. 感谢Yuji Tomita的非常彻底的回答,我的最终解决方案非常接近他的建议,但又有很大的不同,以至于我认为如果其他人遇到与我相同的情况,我会将其发布为另一种选择。

Firstly in my mysite.apps.feedback.models file I put 首先,在我的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 )

In my mysite.apps.feedback.views file I put 在我的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} )

In my mysite.apps.dev.urls file I put 在我的mysite.apps.dev.urls文件中

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

In my mysite.apps.support.urls file I put 在我的mysite.apps.support.urls文件中

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

This will separate feedback messages by app instance. 这将按应用程序实例分隔反馈消息。 Note that my actual code is more complex but this should be good enough for anyone with a similar problem to get a solution up and running pretty quickly. 请注意,我的实际代码更加复杂,但这对于遇到类似问题的任何人来说都足够好,可以迅速启动解决方案并开始运行。 Hope this is useful to anyone in a similar situation. 希望这对处于类似情况的任何人都有用。 Thanks again to Yuji Tomita for the suggestions upon which this solution is based. 再次感谢Yuji Tomita提供此解决方案所依据的建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM