2013-02-15 30 views
6

Tôi có một mô hình người dùng tùy chỉnh mở rộng AbstractUser. Tôi đã thêm hai trường tùy chỉnh. Nhưng tôi muốn trường email mặc định là uniqe và bắt buộc. Tôi đã tìm kiếm rất nhiều trên mạng, nhưng không thể tìm thấy một lời khuyên tốt.Django 1.5 ghi đè trường email trừu tượng để được yêu cầu và duy nhất

Đây có phải là cách thích hợp để làm điều đó trong dạng mở rộng usercreation với phương pháp 'clean_email' bị ghi đè không?

Thanx

Trả lời

0

lẽ bạn có thể ghi đè lên __init__ trên mô hình của bạn để làm cho lĩnh vực này đòi hỏi và độc đáo.

CẬP NHẬT

Sau một chút chơi xung quanh tôi đã thấy điều này nói dễ hơn làm (tôi đã không tìm thấy một cách để làm cho một lĩnh vực trong một lớp trẻ cần trong khi required = False trên công ty mẹ).

+0

Tôi đã tạo mô hình và thêm một số người dùng để tôi không thể ghi đè lên từ mô hình abstractuser mở rộng. Nó cung cấp cho - FieldError: Local field 'email' trong lớp 'CustomUser' xung đột với trường có tên tương tự từ lớp cơ sở 'AbstractUser' - – ratata

+0

nó cho đối tượng 'unicode' không có thuộc tính 'required' error – ratata

+0

Tôi không thể tìm thấy giải pháp cho câu hỏi. Tôi nghĩ rằng nó sẽ là tốt nhất để mở rộng 'AbstractBaseUser'. ??? – ratata

2

email đã có trong số AbstractUser.REQUIRED_FIELDS.

Để làm cho nó độc đáo:

class User(AbstractUser): 
    ... 

(emailField,) = (f for f in User._meta.fields if f.name == "email") 
emailField.unique = True 

Kinda hacky nhưng nên làm việc

Hoặc bạn có thể đơn giản kéo dài tuổi AbstractBaseUser và thêm những thứ còn thiếu từ AbstractUser mình với tùy chỉnh của bạn tweaks

+0

Nếu bạn chạy điều này trong phần chính của lớp 'Người dùng' là không xác định (như là' tự'). Tôi đã thử nó trong '__init__' và nhận' AttributeError: không thể thiết lập thuộc tính'. –

+0

Tôi sẽ không chạy điều này trong '__init__' hoặc bất cứ nơi nào bên trong định nghĩa lớp. Chỉ cần đặt quyền này ** dưới ** định nghĩa lớp – mderk

+0

Trong Django 1.7, nó không hoạt động. Tôi đã tìm thấy giải pháp này hoạt động: http://stackoverflow.com/a/26108834/865664 –

0

mderk của câu trả lời không chính xác làm việc cho tôi - tôi nhận được AttributeError: can't set attribute. Lý do là nội bộ Django tiết kiệm unique 's giá trị trong self._unique.

Vì vậy, để thực hiện một câu chuyện dài ngắn:

class User(AbstractUser): 
    ... 

(emailField,) = (f for f in User._meta.fields if f.name == "email") 
emailField._unique = True 

công trình.

Hoặc thậm chí tốt hơn:

User._meta.get_field('email')._unique = True 
5

Im phải đối mặt với cùng một vấn đề, tôi đang mở rộng AbstractUser như tôi chỉ cần thêm thông tin. Đây là điều duy nhất mà làm việc cho tôi:

AbstractUser._meta.get_field('email')._unique = True 

Đó giải quyết vấn đề duy nhất, nhưng tôi vẫn không thể làm cho nó cần thiết, khi bạn mở rộng AbstractUser lĩnh vực nó email LÀ KHÔNG, nó có thể được nhận thấy nếu bạn thêm một người dùng mở rộng từ quản trị viên và cũng bởi vì các biểu mẫu không mang nó theo cách đó.

Tôi đã thử

AbstractUser._meta.get_field('email')._blank = False 
AbstractUser._meta.get_field('email')._null = False 

Nhưng nó dường như không làm việc.

EDIT: Đối với một số lý do công trình độc đáo với '_', nhưng trống rỗng và không, tôi chỉ cố gắng này

AbstractUser._meta.get_field('email').blank = False 
AbstractUser._meta.get_field('email').null = False 

Và nó làm việc!

+0

SO chắc chắn là hữu ích! ;) Cảm ơn – pztrick

+1

Điều này làm việc trong 1,6 nhưng đăng ký ứng dụng thay đổi với 1.7. Bất kỳ ý tưởng về làm thế nào để thích ứng với câu trả lời này để sử dụng trong 1,7? As-là bạn được nâng lên '' nâng cao AppRegistryNotReady ("Mô hình chưa được tải.") '' – Flowpoke

+0

Xin lỗi Flowpoke, tôi đã không chuyển đến 1.7 nhưng vì vậy tôi không biết làm thế nào để giải quyết nó. – steven2308

0

Hơi khó hiểu mặc dù giải pháp hiệu quả được cung cấp ở đây không hoạt động ở Django 1.7

User._meta.get_field('email')._unique = True 

Điều này là do việc tiếp cận một mô hình trong phạm vi mô-đun vi phạm khẳng định AppRegistry rằng các mô hình không nên được sửa đổi cho đến khi tải xong:

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet. 

Bạn có thể sử dụng tính năng mới App Loading để làm điều này cho bạn. Xác định một lớp AppConfig với phương thức ready có bản vá khỉ trong apps.py trong thư mục ứng dụng của bạn.

from django.apps import AppConfig 

class YourAppConfig(AppConfig): 
    name="your_app_name" 

    def ready(self): 
     from .models import MyAbstractUser 
     MyAbstractUser._meta.get_field_by_name('email')[0]._unique=True 

Giả định rằng MyAbstractUser là phân lớp AbstractUser.

Bạn cũng sẽ phải thay đổi __init__.py trong thư mục của ứng dụng của bạn:

default_app_config = 'your_app_name.apps.YourAppConfig' 

Nếu bạn quên phương pháp ready mới của bạn sẽ không được gọi.

Bây giờ, kiểm tra hệ thống của bạn sẽ được chuyển.

0
AbstractUser._meta.get_field('email')._unique = True 
AbstractUser._meta.get_field('email').blank = False 
AbstractUser._meta.get_field('email').null = False 

Nó hoạt động và tôi đã kiểm tra cơ sở dữ liệu. Tuy nhiên, khi tôi tạo một người dùng từ trang quản trị mặc định, nó sẽ tạo ra nó mà không có vấn đề gì và với trường email trống. Nó sẽ chỉ yêu cầu email khi bạn cố gắng lưu nó. Nhưng nó vẫn là một giải pháp goog. Tôi thậm chí không cần sudo. Tôi khuyên bạn nên đảm bảo rằng bạn yêu cầu email khi tạo người dùng mới từ chế độ xem. * Sử dụng django 1.10 và sqlite3

này cũng sẽ cung cấp cho bạn một ý tưởng về các lĩnh vực bạn có thể ghi đè lên:

(Nếu ai đó tìm thấy một cách để làm cho một trường bắt buộc khi bạn tạo ra nó xin vui lòng để lại nhận xét :))

dir(User._meta.get_field('email')) 
Out[3]: 
['__class__', 
'__copy__', 
'__deepcopy__', 
'__delattr__', 
'__dict__', 
'__doc__', 
'__eq__', 
'__format__', 
'__ge__', 
'__getattribute__', 
'__gt__', 
'__hash__', 
'__init__', 
'__le__', 
'__lt__', 
'__module__', 
'__new__', 
'__reduce__', 
'__reduce_ex__', 
'__repr__', 
'__setattr__', 
'__sizeof__', 
'__str__', 
'__subclasshook__', 
'__unicode__', 
'__weakref__', 
'_blank', 
'_check_backend_specific_checks', 
'_check_choices', 
'_check_db_index', 
'_check_deprecation_details', 
'_check_field_name', 
'_check_max_length_attribute', 
'_check_null_allowed_for_primary_keys', 
'_description', 
'_error_messages', 
'_get_flatchoices', 
'_get_lookup', 
'_get_val_from_obj', 
'_unique', 
'_unregister_lookup', 
'_validators', 
'_verbose_name', 
'attname', 
'auto_created', 
'auto_creation_counter', 
'blank', 
'cached_col', 
'check', 
'choices', 
'class_lookups', 
'clean', 
'clone', 
'column', 
'concrete', 
'contribute_to_class', 
'creation_counter', 
'db_check', 
'db_column', 
'db_index', 
'db_parameters', 
'db_tablespace', 
'db_type', 
'db_type_suffix', 
'deconstruct', 
'default', 
'default_error_messages', 
'default_validators', 
'description', 
'editable', 
'empty_strings_allowed', 
'empty_values', 
'error_messages', 
'flatchoices', 
'formfield', 
'get_attname', 
'get_attname_column', 
'get_cache_name', 
'get_choices', 
'get_col', 
'get_db_converters', 
'get_db_prep_save', 
'get_db_prep_value', 
'get_default', 
'get_filter_kwargs_for_object', 
'get_internal_type', 
'get_lookup', 
'get_pk_value_on_save', 
'get_prep_value', 
'get_transform', 
'has_default', 
'help_text', 
'hidden', 
'is_relation', 
'many_to_many', 
'many_to_one', 
'max_length', 
'model', 
'name', 
'null', 
'one_to_many', 
'one_to_one', 
'pre_save', 
'primary_key', 
'register_lookup', 
'rel', 
'rel_db_type', 
'related_model', 
'remote_field', 
'run_validators', 
'save_form_data', 
'select_format', 
'serialize', 
'set_attributes_from_name', 
'system_check_deprecated_details', 
'system_check_removed_details', 
'to_python', 
'unique', 
'unique_for_date', 
'unique_for_month', 
'unique_for_year', 
'validate', 
'validators', 
'value_from_object', 
'value_to_string', 
'verbose_name'] 
Các vấn đề liên quan