django:修改/扩展第三方应用程序

时间:2011-12-08 14:05:29

标签: django

新手django问题

我想使用第三方应用程序,但我需要为它制作一些mod(在这种情况下,应用程序是django-registration,我需要更改诸如允许注册而无需确认电子邮件的内容)

最初,我只是在一般的site-packages文件夹中安装了应用程序,并在那里更改了代码。现在我将我的代码放在bitbucket上,我需要一种能够以可用的方式将我的mod保存在存储库中的方法,并且上传完整的python代码听起来不是一个好主意。

我想最好的方法是将第三方应用保留在网站包中,并在我的项目中创建一个应用程序以保留我的更改。在我的情况下,我会在我的项目中创建my-django-registration,然后在我的代码中需要它时导入它,而不是django-registration。

我还读到了virtualenv,但我认为这主要用于能够在同一台机器中使用多个环境(实际上,它建议不要更改virtualenv中安装的模块),并且对我没有帮助将我的更改保存在存储库中。

欢迎任何评论! 感谢

3 个答案:

答案 0 :(得分:18)

通常,您应该重复使用并覆盖第三方应用中的行为,而不是修改其来源。

您最常遇到的是应用程序提供的模型可能不一定能满足您的需求,但可以完成大部分工作;你会有几乎完美的形式,但需要那些小东西;如果你能改变一件事,你会有完美的观点;你会得到理智的网址,但你需要更多的东西。

在大多数情况下,这只需要您创建自定义应用并重新连接所有内容。发送您自己的URL,这些URL映射到您已扩展的视图,并覆盖自定义行为的方法;为它提供一个模型表格,Meta正在使用您从原始模型扩展的新模型;等等...

这只是你能做什么的冰山一角,你的创意有更多的方法。我可以给你一个example我如何使用RegistrationProfile模型的方法,但是提供了我自己的网址格式和一个处理注册过程的基于类的自定义视图。

现在,virtualenv发挥作用的地方在于,您最有可能使用piprequirements file format中指定并提供所需的依赖项。那时你想说:“我已经扩展了django-registration应用程序,但它不会干净利用任何版本。它必须是发行版X”,或者“从提交Y的存储库中结账” ”。

答案 1 :(得分:5)

解决此问题的

This blog post非常有帮助。为方便起见,我将其复制粘贴在这里:

您不接触外部应用代码

您不应该从外部应用程序编辑代码。除非你先把它分叉在github上。

那么,如何在不分叉的情况下覆盖:

覆盖模板

如果您要覆盖templates/userena/activate_fail.html,那么您只需创建自己的templates/userena目录并在其中创建自己的activate_fail.html

覆盖网址

您应该在外部应用中检查的第一件事是它的urls.py.正确编码的视图应该支持大量参数。例如,userena有一个带有这种签名的注册视图(在撰写本文时):

def signup(request, signup_form=SignupForm,
       template_name='userena/signup_form.html', success_url=None,
       extra_context=None):

这意味着您可以替换注册视图使用的表单。为此,请打开您的urls.py,在顶部添加我们需要的内容:

from userena import views as userena_views
from yourforms import YourSignupForm

然后,找到包含外部应用程序的网址,例如:

url(r'^userena/', include('userena.urls')),

在此之前,添加您的网址覆盖:

url(r'^userena/signup/$', userena_views.signup, {'signup_form': YourSignupForm}, name='userena_signup'),
url(r'^userena/', include('userena.urls')),

现在,当访问者点击/userena/signup/时,您的自定义网址定义将是第一个被定义的网址。这意味着/userena/signup/将使用YourSignupForm而不是userena的注册表单。

这个技巧适用于任何视图参数。你应该经常看到的是:

  • template_name:允许您更改模板名称
  • extra_context:允许您添加将添加到的字典 上下文

几乎每个观点都应该有这些论点。

覆盖视图

覆盖视图需要覆盖要替换的视图的网址。如果您希望使用自己的注册视图,则只需覆盖网址:

import yourviews

# ...
url(r'^userena/signup/$', yourviews.yoursignup, name='userena_signup'),
url(r'^userena/', include('userena.urls')),

装饰视图

装饰视图就像覆盖视图一样,但重用外部应用程序的视图。基本上,它与覆盖视图相同(见上文),但您的视图将如下所示

from userena import views as userena_views

def yoursignup(request):
    # do stuff before userena signup view is called

    # call the original view
    response = userena_views.signup(request)

    # do stuff after userena signup view is done

    # return the response
    return response

分叉应用

如果您不熟悉pip和virtualenv,请先阅读有关使用pip和virtualenv的帖子。

例如:

  • 你安装了django-userena:pip install django-userena
  • 首先你应该卸载它:pip uninstall django-userena
  • 然后进入应用程序的github页面
  • 点击前叉按钮
  • 这将使您成为一个包含django-userena
  • 副本的存储库
  • 安装如下:pip install -e git+git@github.com:您的-的用户名/ Django的userena.git#蛋= django的-userena
  • 然后您可以编辑yourenv / src / django-userena
  • 中的代码
  • 推送您的提交

致帖子作家的信用!

答案 2 :(得分:0)

我认为实现你所寻找的最好的方法是fork django-registration,并在你的app中使用fork而不是原始项目。

话虽这么说,您可以在django-registration中进行非电子邮件注册,而无需更改应用程序的代码。我已经通过创建自定义registration backend来完成它,该用户将用户设置为在创建时激活。 Here你可以看到其他方法来做同样的事情。