2017-08-24 17 views
6

Tôi biết syncdbmakemigrations, nhưng chúng tôi bị hạn chế làm điều đó trong môi trường sản xuất.Quản trị viên Django - mô hình hiển thị với người siêu người dùng, không phải người dùng của nhân viên

Gần đây, chúng tôi đã có vài bảng được tạo trên sản xuất. Theo dự kiến, các bảng không hiển thị trên quản trị viên cho bất kỳ người dùng nào.
bài viết đó, chúng tôi đã có dưới 2 truy vấn được thực hiện bằng tay trên sql sản xuất (i chạy di cư trên địa phương của tôi và đã làm show create table truy vấn để lấy sql liệu)

django_content_type

INSERT INTO django_content_type(name, app_label, model) 
values ('linked_urls',"urls", 'linked_urls'); 

auth_permission

INSERT INTO auth_permission (name, content_type_id, codename) 
values 
('Can add linked_urls Table', (SELECT id FROM django_content_type where model='linked_urls' limit 1) ,'add_linked_urls'), 
('Can change linked_urls Table', (SELECT id FROM django_content_type where model='linked_urls' limit 1) ,'change_linked_urls'), 
('Can delete linked_urls Table', (SELECT id FROM django_content_type where model='linked_urls' limit 1) ,'delete_linked_urls'); 

Bây giờ thi s mô hình có thể nhìn thấy dưới siêu người dùng và có thể cấp quyền truy cập cho người dùng nhân viên là tốt, nhưng nhân viên người dùng không thể nhìn thấy nó.
Có bất kỳ mục nhập nào cần phải nhập trong đó không?

Hoặc có cách nào khác để giải quyết vấn đề này mà không cần syncdb, di chuyển?

+0

Có thể có một nhóm người dùng _staff_. Bạn có cấp quyền cho nó không? –

+0

vâng, cũng có rất nhiều người dùng độc lập không thuộc nhóm nào! – NoobEditor

+0

Sau đó, tôi khuyên bạn nên tạo nhóm người dùng 'nhân viên' và gán nó cho tất cả người dùng của nhân viên. Tôi không vào đó, nhưng cũng có thể xử lý việc gán bằng một lệnh SQL. –

Trả lời

1

Vì vậy, cuối cùng tôi đã có một giải pháp.Tôi đã làm rất nhiều gỡ lỗi trên django và rõ ràng dưới đây chức năng (tại django.contrib.auth.backends) hiện công việc cung cấp quyền.

def _get_permissions(self, user_obj, obj, from_name): 
    """ 
    Returns the permissions of `user_obj` from `from_name`. `from_name` can 
    be either "group" or "user" to return permissions from 
    `_get_group_permissions` or `_get_user_permissions` respectively. 
    """ 
    if not user_obj.is_active or user_obj.is_anonymous() or obj is not None: 
     return set() 

    perm_cache_name = '_%s_perm_cache' % from_name 
    if not hasattr(user_obj, perm_cache_name): 
     if user_obj.is_superuser: 
      perms = Permission.objects.all() 
     else: 
      perms = getattr(self, '_get_%s_permissions' % from_name)(user_obj) 
     perms = perms.values_list('content_type__app_label', 'codename').order_by() 
     setattr(user_obj, perm_cache_name, set("%s.%s" % (ct, name) for ct, name in perms)) 
    return getattr(user_obj, perm_cache_name) 

Vì vậy, vấn đề là gì?

Issue nói dối trong truy vấn này:

INSERT INTO django_content_type(name, app_label, model) 
values ('linked_urls',"urls", 'linked_urls'); 

có vẻ tốt đẹp ban đầu nhưng truy vấn thực tế thực hiện là:

--# notice the caps case here - it looked so trivial, i didn't even bothered to look into it untill i realised what was happening internally 
INSERT INTO django_content_type(name, app_label, model) 
values ('Linked_Urls',"urls", 'Linked_Urls'); 

Vì vậy django, trong nội bộ, khi thực hiện migrate, đảm bảo mọi thứ được di cư trong thấp case - và đây là vấn đề !!

Tôi đã thực hiện truy vấn riêng biệt để giảm bớt tất cả các lần chèn trước và voila!

3

Gần đây, chúng tôi đã có vài bảng được tạo trên sản xuất.

Tôi có thể đọc những gì bạn đã viết ở đó theo hai cách.

Cách đầu tiên: bạn đã tạo bảng với câu lệnh SQL, không có mô hình tương ứng trong Django. Nếu đây là trường hợp, không có số lượng fiddling với các loại nội dung và các điều khoản mà sẽ làm cho Django đột nhiên sử dụng các bảng. Bạn cần tạo các mô hình cho các bảng. Có thể họ sẽ là unmanaged, nhưng họ cần phải tồn tại.

Cách thứ hai: các mô hình tương ứng trong Django tồn tại, bạn chỉ cần tạo bảng theo cách thủ công cho chúng, vì vậy đó không phải là vấn đề. Những gì tôi muốn làm trong trường hợp này được điều hành đoạn mã sau, giải thích làm theo sau khi mã:

from django.contrib.contenttypes.management import update_contenttypes 
from django.apps import apps as configured_apps 
from django.contrib.auth.management import create_permissions 

for app in configured_apps.get_app_configs(): 
    update_contenttypes(app, interactive=True, verbosity=0) 

for app in configured_apps.get_app_configs(): 
    create_permissions(app, verbosity=0) 

gì đoạn mã trên không cơ bản được thực hiện công việc mà Django thực hiện sau nó chạy di cư. Khi di chuyển xảy ra, Django chỉ tạo bảng khi cần thiết, sau đó khi nó được thực hiện, nó gọi update_contenttypes, quét bảng liên kết với các mô hình được xác định trong dự án và thêm vào bảng django_content_type bất cứ điều gì cần phải được thêm vào. Sau đó, nó gọi số create_permissions để cập nhật auth_permissions với quyền thêm/thay đổi/xóa cần thêm. Tôi đã sử dụng mã ở trên để buộc các quyền được tạo sớm during a migration. Nó rất hữu ích nếu tôi có một di chuyển dữ liệu, ví dụ, tạo ra các nhóm cần phải tham khảo các điều khoản mới.

+0

cách thứ hai của bạn mà bạn đã đề cập. Bây giờ, vấn đề của tôi là tôi không có quyền truy cập để chạy những thứ trên shell trên prod/pre-prod.Is có bất kỳ công cụ 'sql' thô nào mà tôi có thể chuyển sang DBA để thực hiện truy vấn và hoàn thành công việc? – NoobEditor

+0

Bạn không gặp phải vấn đề đó. Bất kỳ lệnh quản lý Django có thể được chạy bằng cách gọi 'django.core.management.call_command' từ mã python. Nếu bạn tạo một khung nhìn kết thúc tốt chức năng đó, bạn có thể chạy bất cứ thứ gì bạn muốn. Nhưng, khi nghi ngờ, bạn cũng có thể gọi một lệnh từ python và như một khung nhìn Django bằng cách sử dụng thư viện [subprocess] (https://docs.python.org/3/library/subprocess.html). Và có, cả hai cách sẽ cho phép bạn chạy di chuyển. – Melvyn

Các vấn đề liên quan