我在django写了一个简单的反馈应用程序。它并不是特别复杂,基本上它允许经过身份验证的用户使用主题行编写镜头消息并通过表单提交该消息。然后,我允许选定组中的人查看用户提交的反馈。在未来,我可能会添加更多功能,但现在它可以实现我想要的功能。
这是我的问题,我正在建设的网站有多个地方我想使用反馈应用程序,例如我有一个“您对该网站有什么看法?” /dev/feedback/
处的页面类型我还在“/ support / feedback /”上有一个用于客户支持反馈的页面。目前我刚刚将mysite.apps.dev.feedback
的代码复制到mysite.apps.support.feedback
。
问题在于,它现在已经创建了相同代码的两个单独副本。尽管刚刚编写了应用程序,但两个版本已经开始出现分歧,这很烦人。我的问题是如何在具有不同数据库模型的django站点中创建同一应用程序的多个实例?
我发现相关但没有帮助的一些资源是https://docs.djangoproject.com/en/dev/topics/http/urls/和Reversing namespaced URLs in Django: multiple instances of the same app第一页没有提供太多关于此问题的信息,而第二页提供了一些似乎同时存在的一些不切实际和不切实际的解决方案与他们的价值无关,更多的工作。有没有一种正确的方法来实现相同的django应用程序的多个实例?
答案 0 :(得分:3)
我个人会尝试将此作为一个应用程序保留,并有一个视图,可以处理从多个位置发布/适当标记它们。
正如S.Lott所说,这是要走的路。如果您对在其他情况下将代码保存在一个地方的方法感到好奇,我会提供替代方案。
例如,您可以在模型中添加category
字段,设置一个url conf,接受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,然后为不同的表创建子类。这应该可以解决您的代码不同步的问题。
您将拥有一个抽象模型(没有表格),您的单独应用中的“真实”模型将基于这些模型。
如果必须有单独的模型,则可以编写动态构造的视图。
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))
答案 1 :(得分:2)
如何在具有不同数据库模型的django站点中创建同一应用程序的多个实例?
你不应该。
您只需使用其他两个应用中的反馈应用模型,只需from feedback.models import Feedback
。
然后,您的support
应用可以创建,检索,更新和删除反馈对象。
您的dev
应用程序同样可以创建,检索,更新和删除Feedback对象,因为它导入了模型。
这就是所需要的:import
。
答案 2 :(得分: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提出的解决方案所依据的建议。