0

モデルで:

class Author(models.Model):
    author_name = models.CharField(max_length=50)
    email = models.CharField(max_length=100)
    editor =  ProfiledUserField(User)

    def __str__(self):
        return '%s'%(self.author_name)

カスタム ProfiledUserField

from django.db import models
from django.contrib.auth.models import User
from django.db.models.fields.related import ForeignKey
from django.forms.fields import Select, TextInput
import datetime

class ProfiledUser(object):
    def __init__(self,user_id):
        self.user_id = user_id

    def get_user(self):
        return self.user

    def create_user(self,username,password="user123"):
        user = User.objects.create(username=username,password=password)
        return user


class ProfiledUserField(ForeignKey):
    description = "a custom user field"
    __metaclass__ = models.SubfieldBase

    def __init__(self,*args,**kwargs):
        return super(ProfiledUserField,self).__init__(*args,**kwargs)

    def to_python(self,value):
        return value


    def get_prep_value(self,value):
        print 'in get prep value',datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M:%f")
        return value.id

    def get_db_prep_value(self,value,connection,prepared=False):
        print 'in get Db prep value',datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M:%f")
        return value.id

モデルを登録する以外に、管理セクションには何もありません。

管理者経由でオブジェクトを保存しようとすると、to_python が 2 回呼び出されます。最初は選択ウィジェットから選択されたユーザー オブジェクトで、2 回目は値 None で呼び出されます。呼び出されると、検証エラー「フィールドを空白のままにすることはできません」が発生します(エディターはデフォルトでnullまたは空白にできないため)

Pythonシェル経由で保存しようとすると、

>>> author= Author.objects.create(author_name="Khalil Gibran" , email="kh@gmail.com", editor=user)
AttributeError: 'Author' object has no attribute 'editor_id'

>>> Author
<class 'articles.models.Author'>
>>> Author.__dict__
dict_proxy({'__module__': 'articles.models', 'MultipleObjectsReturned': <class 'articles.models.MultipleObjectsReturned'>, '_meta': <Options for Author>, '__str__': <function __str__ at 0x97d0d4c>, 'article_set': <django.db.models.fields.related.ForeignRelatedObjectsDescriptor object at 0x97e0b0c>, '_base_manager': <django.db.models.manager.Manager object at 0x97e02ec>, 'objects': <django.db.models.manager.ManagerDescriptor object at 0x97e034c>, 'editor': <django.db.models.fields.subclassing.Creator object at 0x97e024c>, 'DoesNotExist': <class 'articles.models.DoesNotExist'>, '__doc__': 'Author(id, author_name, email, editor_id)', '_default_manager': <django.db.models.manager.Manager object at 0x97e02ec>})
>>> dir(Author)
['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_base_manager', '_default_manager', '_deferred', '_get_FIELD_display', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_set_pk_val', 'article_set', 'clean', 'clean_fields', 'date_error_message', 'delete', 'editor', 'full_clean', 'objects', 'pk', 'prepare_database_save', 'save', 'save_base', 'serializable_value', 'unique_error_message', 'validate_unique']

ysql シェル:

mysql> describe articles_author;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| author_name | varchar(50)  | NO   |     | NULL    |                |
| email       | varchar(100) | NO   |     | NULL    |                |
| editor_id   | int(11)      | NO   | MUL | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

私は何を間違っていますか?

モデルにnull = True、blank = Trueがあった場合、同じコードは完全に正常に機能しますが、それ以外の場合は保存できません。メタクラス=Subfieldbaseを削除すると、すべて正常に動作します。説明は何ですか?

4

0 に答える 0