2014-10-20 45 views
33

我有一個數據遷移更新了一些權限。我知道有一些已知的遷移權限問題,我可以通過在遷移中創建權限(而不是使用模型中的元組快捷方式)來避免一些麻煩。在遷移中獲取模型ContentType - Django 1.7

遷移:

from __future__ import unicode_literals 
from django.db import migrations, models 
from django.conf import settings 

def create_feature_groups(apps, schema_editor): 
    app = models.get_app('myauth') 

    Group = apps.get_model("auth", "Group") 
    pro = Group.objects.create(name='pro') 

    Permission = apps.get_model("auth", "Permission") 
    ContentType = apps.get_model("contenttypes", "ContentType") 
    invitation_contenttype = ContentType.objects.get(name='Invitation') 

    send_invitation = Permission.objects.create(
     codename='send_invitation', 
     name='Can send Invitation', 
     content_type=invitation_contenttype) 

    pro.permissions.add(receive_invitation)  

class Migration(migrations.Migration): 

    dependencies = [ 
     ('myauth', '0002_initial_data'), 
    ] 

    operations = [ 
      migrations.RunPython(create_feature_groups), 
    ] 

一些試驗和錯誤後,我能夠用manage.py migrate,使這項工作,但我發現在測試manage.py test錯誤。

__fake__.DoesNotExist: ContentType matching query does not exist. 

調試了一下發現,在試運行時(不知道爲什麼)沒有ContentType在遷移至此。按照post的建議,我嘗試在自己的遷移中手動更新內容類型。補充:

from django.contrib.contenttypes.management import update_contenttypes 
update_contenttypes(app, models.get_models()) 

取爲Invitation模型的內容類型之前。得到了以下錯誤

File "C:\Python27\lib\site-packages\django-1.7-py2.7.egg\django\contrib\contenttypes\management.py", line 14, in update_contenttypes 
    if not app_config.models_module: 
AttributeError: 'module' object has no attribute 'models_module' 

必須有一些方式可測試的方式來創建數據遷移/更新的權限。

謝謝。

編輯

最後使它加入

from django.contrib.contenttypes.management import update_all_contenttypes 
update_all_contenttypes() 

奇怪的是這一次是不夠的

update_contenttypes(apps.app_configs['contenttypes']) 

我很想知道爲什麼這一切的是需要

工作
+0

對於那些Django的1.8誰想要update_all_contenttypes,請參考這個問題:http://stackoverflow.com/questions/29550102/importerror-cannot -import-name-update-all-contenttypes – jstaab 2015-09-09 23:31:01

回答

6

有一個simila在編寫跨越多個應用程序的數據遷移時遇到問題。原來,Django只會將這些模型加載到應用程序註冊表中,受遷移狀態的「依賴關係」成員影響:https://code.djangoproject.com/ticket/24303

必須基本上向我使用的遷移依賴項添加條目,例如當前正在遷移的應用程序的ForeignKey。

+0

我不明白。你如何確定哪些(不相關的)遷移需要添加爲模型的依賴關係? – haki 2015-02-15 11:46:29

+0

基本上,我添加了所有我想用作數據遷移一部分的模型的應用程序。 – Sakuraba 2015-03-13 09:30:35

+0

除了運行update_all_contenttypes(感謝提示),您應該包含('contenttypes','0001_initial')作爲遷移依賴項。 – chk 2015-05-11 09:09:31

1
update_contenttypes(apps.app_configs['contenttypes']) 

將更新contenttypes應用的內容類型。

我相信你會想這樣做......

update_contenttypes(apps.app_configs['app_label']) 

其中app_label是應用程序,其中邀請模型lives.This將更新您的單一的應用程序的內容類型,所以這將是可用的應用程序標籤按照您的原始代碼進行查詢。

3

因爲,我最終花了3-4個小時在這個上面,我正在添加我的解決方案。

問題是當我將多個遷移一起運行時,ContentType和Permission對象未創建。由於我在下一次遷移時引用了這些內容類型和遷移,這就造成了問題。)

但是,如果我使用遷移編號逐個運行它們,它們將正常工作。 (在未來的遷移中被引用)

爲了解決這個問題,我添加了一個額外的遷移來創建ContentType和Permission對象。

- - 編碼:UTF-8 - -

# Generated by Django 1.10.6 on 2017-03-11 05:59 
from __future__ import unicode_literals 

from django.conf import settings 
from django.db import migrations 


def update_all_contenttypes(**kwargs): 
    from django.apps import apps 
    from django.contrib.contenttypes.management import update_contenttypes 

    for app_config in apps.get_app_configs(): 
     update_contenttypes(app_config, **kwargs) 


def create_all_permissions(**kwargs): 
    from django.contrib.auth.management import create_permissions 
    from django.apps import apps 

    for app_config in apps.get_app_configs(): 
     create_permissions(app_config, **kwargs) 


def forward(apps, schema_editor): 
    update_all_contenttypes() 
    create_all_permissions() 


def backward(apps, schema_editor): 
    pass 


class Migration(migrations.Migration): 
    dependencies = [ 
     migrations.swappable_dependency(settings.AUTH_USER_MODEL), 
     ('contenttypes', '0002_remove_content_type_name'), 
     ('MY_APP', '0123_LAST_MIGRATION'), 
    ] 

    operations = [ 
     migrations.RunPython(forward, backward) 
    ] 
+2

使用Django 1.11 update_contenttypes不再存在,請改用create_contenttypes – oden 2017-05-15 03:25:54