Сделать поля первичного ключа редактируемыми в Flask-Admin

Я использую Flask-Admin для своего проекта на основе Flask. В нем у меня есть несколько моделей (использующих peewee), в которых первичный ключ задается пользователем, например username для User. Однако Flask-Admin не отображает эти поля на страницах создания/редактирования модели.

Теперь, когда я пытаюсь создать нового пользователя, кнопка «Сохранить» выдает ошибку peewee.UserDoesNotExist, а «Сохранить и добавить» дважды говорит «Запись успешно создана», но на самом деле ничего не делает.

Я расширил метод save() для автоматического создания имени пользователя из имени, если оно не задано, но проблема не исчезла, даже когда я удалил переопределение.

Код...

Вот как выглядит моя модель пользователя:

# import peewee as pw

class User(BaseModel, UserMixin):
    username = pw.CharField(32, primary_key=True)
    password = pw.CharField(512, null=True)
    name = pw.CharField(64)

    # ... other fields not shown ... #

    def save(self, *args, **kwargs):
        # Set the username if field is blank
        if self.username == 'auto' or not self.username:
            self.username = self.name.replace(' ', '').lower()
        # Do the real save
        super(User, self).save(*args, **kwargs)

Вот мой код администратора:

# from flask_admin.contrib.peewee.view import ModelView

class AdminModelUser(ModelView):
    can_create = True
    column_list = ('username', 'name', 'group', 'active')

admin.add_view(AdminModelUser(User, name='Users', category='Accounts'))

Пробуем

Позже я попытался переопределить метод get_form(), чтобы напрямую использовать wtfpeewee и разрешить pk, например:

# from wtfpeewee.orm import model_form
class AdminModelUser(ModelView):
    ...        
    def get_form(self):
        return model_form(User, allow_pk=True)

Сейчас поле показывает, но сохранить все равно не получается. Когда я редактирую имя пользователя существующего пользователя, администратор говорит: «Запись успешно сохранена», но она не сохраняется. И когда я пытаюсь создать нового пользователя, я все равно получаю ошибку peewee.UserDoesNotExist.

Я предполагаю, что я сделал переопределение в неправильном месте, и поля отображаются в форме, но не в методах сохранения. Я не мог найти упоминания об этом в документах: кто-нибудь знает, как это сделать?


person Hippo    schedule 03.07.2015    source источник
comment
Причина, по которой вы получаете peewee.UserDoesNotExist, скорее всего, заключается в том, что SQL, сгенерированный после изменения имени пользователя, представляет собой что-то вроде UPDATE some_table SET (...) WHERE id=new_username, которого, очевидно, не существует. Я бы настоятельно рекомендовал не использовать первичный идентификатор, установленный пользователем. Гораздо безопаснее и проще использовать автоматически увеличивающийся целочисленный идентификатор.   -  person kylieCatt    schedule 03.07.2015
comment
Вы создаете много ненужной работы для себя и своей базы данных, редактируя первичные ключи. Придерживайтесь целых чисел или UUID и используйте уникальные ограничения для значимых полей, которые должны быть уникальными, например имя пользователя.   -  person dirn    schedule 03.07.2015


Ответы (1)


Когда у вас есть нецелочисленный первичный ключ, вы должны вызвать save() с force_insert=True, чтобы добавить новую строку.

http://docs.peewee-orm.com/en/latest/peewee/models.html#non-integer-primary-keys-composite-keys-and-other-tricks

person coleifer    schedule 05.07.2015
comment
Спасибо. В конце концов я решил воздержаться от модификации pk, но на случай, если мне когда-нибудь понадобится, теперь я знаю, как это сделать (я проверял, и это сработало)! - person Hippo; 13.07.2015