如何在新项目中开发/包含Django自定义可重用应用程序?有一些指导方针吗?

时间:2022-02-13 10:59:31

following tutorial on Django reusable apps things work fine. But I have some questions on the process of developing and packaging a Django app.

关于Django可重用应用程序的以下教程,工作正常。但是我对开发和打包Django应用程序的过程有一些疑问。

1 - In the tutorial, the app is developed first within a project, then copy-paste'd out in another folder for packaging, and then included again in the project vía pip. Is this the way for developing Django apps? For example, if I have to include new features or fix bugs, Should I make changes in the project and then copy-paste them to the package folder outside the project?

1 - 在教程中,应用程序首先在项目中开发,然后在另一个文件夹中进行复制粘贴以进行打包,然后再次包含在项目中。这是开发Django应用程序的方式吗?例如,如果我必须包含新功能或修复错误,我是否应该在项目中进行更改,然后将它们复制粘贴到项目外的包文件夹中?

2 - Assuming that 1 is not the only way to develop an app, I started creating a package folder for my app with this structure:

2 - 假设1不是开发应用程序的唯一方法,我开始使用以下结构为我的应用程序创建一个包文件夹:

django-myApp
|--myApp
|  |--models
|     |--file1.py
|     |--file2.py
|--setup.py
|--README.rst

After running python3 setup.py sdist and installing it with pip3 install --user myApp.tar.gz I can successfully import my app from a new Django project shell. But when I run python3 manage.py migrate, tables for models of myApp are not created. I guess it is because there is not migration folder in myApp package, and as far as I know, the only way to create migrations is running makemigrations within a project. Or may I am missing something? Can I generate initial migration module without having the app in a project?

运行python3 setup.py sdist并使用pip3 install -user myApp.tar.gz安装后,我可以从新的Django项目shell成功导入我的应用程序。但是当我运行python3 manage.py migrate时,不会创建myApp模型的表。我想这是因为myApp包中没有迁移文件夹,据我所知,创建迁移的唯一方法是在项目中运行makemigrations。或者我可能错过了什么?我是否可以在项目中没有应用程序的情况下生成初始迁移模块?

3 - Finally, the question is: When developing an app, Should I have to start a project, copy out the app folder for packaging, reincluding it vía installing, and then continue developing in the package folder?

3 - 最后,问题是:在开发应用程序时,我是否必须启动项目,复制app文件夹进行打包,重新安装它,然后继续开发包文件夹?

Thanks in advance for any comment or guidance.

提前感谢任何评论或指导。

P.D.: Sorry for my English, also comments about it are well-received

P.D。:对不起我的英文,也对它的评论很受欢迎

EDIT 1:

编辑1:

An example to highlight my doubt: After finish tutorial, App source code is outside the project and suppose I need to change models. I can change them in app folder, release a new version (e.g. 0.2) and install it. Now, How can I generate migrations for these changes? Should I always have a test project?

一个突出我的疑问的例子:完成教程后,应用程序源代码在项目之外,并假设我需要更改模型。我可以在app文件夹中更改它们,发布新版本(例如0.2)并安装它。现在,如何为这些更改生成迁移?我应该总是有一个测试项目吗?

3 个解决方案

#1


9  

Additionally, a good workflow during development is to link the reusable app into your Django project. To easily achieve this pip install has the -e, --editable option, which in turn derives from the setuptools Development mode.

此外,开发过程中的良好工作流程是将可重用的应用程序链接到您的Django项目中。要轻松实现此pip安装,请使用-e, - edit选项,该选项又来自setuptools开发模式。

Reusable app:

可重复使用的应用:

django-myApp
|--myApp
|  |--models
|     |--file1.py
|     |--file2.py
|--setup.py
|--README.rst

Django setup:

Django设置:

my-django-project
|--my_django_project
|  |--settings.py
|  |--urls.py
|  |--wsgi.py
|  |--...
|--manage.py

With your virtualenv activated you can now link your reusable app to the project by running:

激活virtualenv后,您现在可以通过运行以下链接将可重用应用程序链接到项目:

(myvenv) $ pip install --editable /path/to/django-myApp

Now, every change that you make in django-myApp is automatically reflected in my-django-project without the need to build/package the reusable app first.

现在,您在django-myApp中进行的每个更改都会自动反映在my-django项目中,而无需首先构建/打包可重用的应用程序。

This becomes convenient in many use cases. E.g. imagine developing the app to be compatible with Python 2.x and Python 3.x. With linking, you can install the app into two (or more) different Django setups and run your tests.

这在许多用例中变得方便。例如。想象一下开发应用程序以兼容Python 2.x和Python 3.x.通过链接,您可以将应用程序安装到两个(或更多)不同的Django设置中并运行测试。

#2


3  

  1. When you package an app, is because you decided it was worth to use it across several projects and had some value on it's own. You can follow the guidelines to keep your app reusable and package once it is in a good state (minimal functionality working). Ok, you got your app ready, it does what you want, so now you want to separate it from your project? Follow the tutorial you linked for the guidelines on the folder structure and upload it to a repository. Add some tests too, they are a must have. You can now use a couple approaches to get it back into your project.

    当你打包应用程序时,是因为你决定在几个项目中使用它并且有自己的价值。您可以遵循这些指南,以确保您的应用程序可以重复使用,并在其处于良好状态时进行打包(最小功能正常工作)。好的,你准备好你的应用程序,它可以做你想要的,所以现在你想把它与你的项目分开?按照您链接的教程获取有关文件夹结构的指南,并将其上载到存储库。添加一些测试,它们是必须的。您现在可以使用几种方法将其恢复到项目中。

    • Package it and install it from the tar.gz via pip (or directly from repository)
    • 打包并通过pip(或直接从存储库)从tar.gz安装它
    • Clone your repository as a submodule
    • 将您的存储库克隆为子模块
    • Keep a copy in your project and update changes manually in the repository
    • 在项目中保留一份副本,并在存储库中手动更新更改

I am not a fan of third one. Second option has its caveats but it can work. I definitely prefer first one.

我不是第三个的粉丝。第二种选择有其警告,但它可以工作。我绝对喜欢第一个。

Create a test project around your new app and use it to develop it's new features (with just the minimum requirements to test it), update your repository and finally update the app in your project via pip. Your app is now something that doesn't depend on your project, so don't tie your app to it.

围绕新应用程序创建一个测试项目,并使用它来开发它的新功能(只需要测试它的最低要求),更新存储库,最后通过pip更新项目中的应用程序。您的应用现在不依赖于您的项目,因此不要将您的应用绑定到它。

  1. Did you add it to your INSTALLED_APPS? If you did, check that your models.py is accesible...try with the django shell. Try creating the migrations module to see if it works, that doesn't take long anyway.

    你有没有把它添加到你的INSTALLED_APPS?如果你这样做,请检查你的models.py是否可访问...尝试使用django shell。尝试创建迁移模块以查看它是否有效,无论如何都不需要很长时间。

  2. Finally the answer: No, your app is a different project on it's own now, you continue developing on a repository like you would do with any other project and then update like you would do with any other app that got a new version released. You don't need (nor should) touch your virtualenv's folders at all.

    最后答案是:不,你的应用程序现在是一个不同的项目,你继续在存储库上开发,就像你对任何其他项目一样,然后像你对任何其他发布新版本的应用程序一样进行更新。您根本不需要(也不应该)触摸virtualenv的文件夹。

These are the steps for an update in your app:

以下是您的应用中更新的步骤:

  • You found a nasty bug or thought of some nice feature
  • 你发现了一个讨厌的bug或想到了一些不错的功能
  • You added the tests to cover it
  • 您添加了测试以覆盖它
  • You updated your code to enhance your app
  • 您更新了代码以增强您的应用
  • You repeat the last couple steps until your app is stable again
  • 您重复最后几步,直到您的应用再次稳定
  • If your app is in Pypi, you release a new package and update it from there, otherwise you update it from the repository.
  • 如果您的应用程序位于Pypi中,则会发布新软件包并从那里进行更新,否则您将从存储库更新它。

This obviously takes longer than developing an app inside of your project, but doing it this way helps ensuring a good quality and that it won't introduce problems to your projects.

这显然需要比在项目中开发应用程序更长的时间,但这样做有助于确保良好的质量,并且不会给项目带来问题。

#3


0  

I ran into a similar situation while developing this library (django-nsync).

我在开发这个库(django-nsync)时遇到了类似的情况。

I "solved" the issue by creating a makemigrations.py script that sets up a minimal Django settings to include the 'app' and then makes a call to the makemigrations command.

我通过创建一个makemigrations.py脚本“解决”了这个问题,该脚本设置了一个最小的Django设置以包含'app',然后调用makemigrations命令。

The script looks like this:

脚本如下所示:

def make_migrations():
    from django.core.management import call_command
    call_command('makemigrations', '<YOUR APP NAME>')


if __name__ == '__main__':
    import sys
    # I need to add the 'src' folder to PYTHON PATH
    sys.path.append('./src/')

    try:
        from django.conf import settings

        settings.configure(
            INSTALLED_APPS=[
                '<ANY APPS YOUR APP DEPENDS ON>',
                '<YOUR APP NAME>',
            ],
        )

        import django
        django.setup()

    except ImportError:
        import traceback
        traceback.print_exc()
        raise ImportError('To fix this error, sort out the imports')

    make_migrations()

This script does not require a separate project in order to create the migrations.

此脚本不需要单独的项目来创建迁移。

NB: I tried to hook this into the setup.py stuff so that whenever you try to build (or more importantly release) the library it checks that the migrations are up to date / in source control. However, I gave up because:

注意:我试图将其挂钩到setup.py中,以便每当您尝试构建(或更重要的是发布)库时,它都会检查迁移是否为源代码控制中的最新版本。但是,我放弃了因为:

  1. I hopefully won't have to do it much for the NSync library.
  2. 我希望不必为NSync库做很多事情。
  3. It got messy quickly (like checking how many files in the migrations folder, then running the migrations, then checking again, then deleting the files? or leaving them? should I enforce this at release time? should I check with Git like bumpversion does? blah....)
  4. 它很快就乱了(比如检查迁移文件夹中有多少文件,然后运行迁移,然后再次检查,然后删除文件?或者离开它们?我应该在发布时强制执行吗?我应该像Git一样检查颠倒吗?等等....)

#1


9  

Additionally, a good workflow during development is to link the reusable app into your Django project. To easily achieve this pip install has the -e, --editable option, which in turn derives from the setuptools Development mode.

此外,开发过程中的良好工作流程是将可重用的应用程序链接到您的Django项目中。要轻松实现此pip安装,请使用-e, - edit选项,该选项又来自setuptools开发模式。

Reusable app:

可重复使用的应用:

django-myApp
|--myApp
|  |--models
|     |--file1.py
|     |--file2.py
|--setup.py
|--README.rst

Django setup:

Django设置:

my-django-project
|--my_django_project
|  |--settings.py
|  |--urls.py
|  |--wsgi.py
|  |--...
|--manage.py

With your virtualenv activated you can now link your reusable app to the project by running:

激活virtualenv后,您现在可以通过运行以下链接将可重用应用程序链接到项目:

(myvenv) $ pip install --editable /path/to/django-myApp

Now, every change that you make in django-myApp is automatically reflected in my-django-project without the need to build/package the reusable app first.

现在,您在django-myApp中进行的每个更改都会自动反映在my-django项目中,而无需首先构建/打包可重用的应用程序。

This becomes convenient in many use cases. E.g. imagine developing the app to be compatible with Python 2.x and Python 3.x. With linking, you can install the app into two (or more) different Django setups and run your tests.

这在许多用例中变得方便。例如。想象一下开发应用程序以兼容Python 2.x和Python 3.x.通过链接,您可以将应用程序安装到两个(或更多)不同的Django设置中并运行测试。

#2


3  

  1. When you package an app, is because you decided it was worth to use it across several projects and had some value on it's own. You can follow the guidelines to keep your app reusable and package once it is in a good state (minimal functionality working). Ok, you got your app ready, it does what you want, so now you want to separate it from your project? Follow the tutorial you linked for the guidelines on the folder structure and upload it to a repository. Add some tests too, they are a must have. You can now use a couple approaches to get it back into your project.

    当你打包应用程序时,是因为你决定在几个项目中使用它并且有自己的价值。您可以遵循这些指南,以确保您的应用程序可以重复使用,并在其处于良好状态时进行打包(最小功能正常工作)。好的,你准备好你的应用程序,它可以做你想要的,所以现在你想把它与你的项目分开?按照您链接的教程获取有关文件夹结构的指南,并将其上载到存储库。添加一些测试,它们是必须的。您现在可以使用几种方法将其恢复到项目中。

    • Package it and install it from the tar.gz via pip (or directly from repository)
    • 打包并通过pip(或直接从存储库)从tar.gz安装它
    • Clone your repository as a submodule
    • 将您的存储库克隆为子模块
    • Keep a copy in your project and update changes manually in the repository
    • 在项目中保留一份副本,并在存储库中手动更新更改

I am not a fan of third one. Second option has its caveats but it can work. I definitely prefer first one.

我不是第三个的粉丝。第二种选择有其警告,但它可以工作。我绝对喜欢第一个。

Create a test project around your new app and use it to develop it's new features (with just the minimum requirements to test it), update your repository and finally update the app in your project via pip. Your app is now something that doesn't depend on your project, so don't tie your app to it.

围绕新应用程序创建一个测试项目,并使用它来开发它的新功能(只需要测试它的最低要求),更新存储库,最后通过pip更新项目中的应用程序。您的应用现在不依赖于您的项目,因此不要将您的应用绑定到它。

  1. Did you add it to your INSTALLED_APPS? If you did, check that your models.py is accesible...try with the django shell. Try creating the migrations module to see if it works, that doesn't take long anyway.

    你有没有把它添加到你的INSTALLED_APPS?如果你这样做,请检查你的models.py是否可访问...尝试使用django shell。尝试创建迁移模块以查看它是否有效,无论如何都不需要很长时间。

  2. Finally the answer: No, your app is a different project on it's own now, you continue developing on a repository like you would do with any other project and then update like you would do with any other app that got a new version released. You don't need (nor should) touch your virtualenv's folders at all.

    最后答案是:不,你的应用程序现在是一个不同的项目,你继续在存储库上开发,就像你对任何其他项目一样,然后像你对任何其他发布新版本的应用程序一样进行更新。您根本不需要(也不应该)触摸virtualenv的文件夹。

These are the steps for an update in your app:

以下是您的应用中更新的步骤:

  • You found a nasty bug or thought of some nice feature
  • 你发现了一个讨厌的bug或想到了一些不错的功能
  • You added the tests to cover it
  • 您添加了测试以覆盖它
  • You updated your code to enhance your app
  • 您更新了代码以增强您的应用
  • You repeat the last couple steps until your app is stable again
  • 您重复最后几步,直到您的应用再次稳定
  • If your app is in Pypi, you release a new package and update it from there, otherwise you update it from the repository.
  • 如果您的应用程序位于Pypi中,则会发布新软件包并从那里进行更新,否则您将从存储库更新它。

This obviously takes longer than developing an app inside of your project, but doing it this way helps ensuring a good quality and that it won't introduce problems to your projects.

这显然需要比在项目中开发应用程序更长的时间,但这样做有助于确保良好的质量,并且不会给项目带来问题。

#3


0  

I ran into a similar situation while developing this library (django-nsync).

我在开发这个库(django-nsync)时遇到了类似的情况。

I "solved" the issue by creating a makemigrations.py script that sets up a minimal Django settings to include the 'app' and then makes a call to the makemigrations command.

我通过创建一个makemigrations.py脚本“解决”了这个问题,该脚本设置了一个最小的Django设置以包含'app',然后调用makemigrations命令。

The script looks like this:

脚本如下所示:

def make_migrations():
    from django.core.management import call_command
    call_command('makemigrations', '<YOUR APP NAME>')


if __name__ == '__main__':
    import sys
    # I need to add the 'src' folder to PYTHON PATH
    sys.path.append('./src/')

    try:
        from django.conf import settings

        settings.configure(
            INSTALLED_APPS=[
                '<ANY APPS YOUR APP DEPENDS ON>',
                '<YOUR APP NAME>',
            ],
        )

        import django
        django.setup()

    except ImportError:
        import traceback
        traceback.print_exc()
        raise ImportError('To fix this error, sort out the imports')

    make_migrations()

This script does not require a separate project in order to create the migrations.

此脚本不需要单独的项目来创建迁移。

NB: I tried to hook this into the setup.py stuff so that whenever you try to build (or more importantly release) the library it checks that the migrations are up to date / in source control. However, I gave up because:

注意:我试图将其挂钩到setup.py中,以便每当您尝试构建(或更重要的是发布)库时,它都会检查迁移是否为源代码控制中的最新版本。但是,我放弃了因为:

  1. I hopefully won't have to do it much for the NSync library.
  2. 我希望不必为NSync库做很多事情。
  3. It got messy quickly (like checking how many files in the migrations folder, then running the migrations, then checking again, then deleting the files? or leaving them? should I enforce this at release time? should I check with Git like bumpversion does? blah....)
  4. 它很快就乱了(比如检查迁移文件夹中有多少文件,然后运行迁移,然后再次检查,然后删除文件?或者离开它们?我应该在发布时强制执行吗?我应该像Git一样检查颠倒吗?等等....)