django: расширение пользовательской модели, используя один-к-одному: как сохранить () поля модели профиля - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть базовое приложение Django, в котором наряду с моделью User я расширил модель Profile с помощью поля One-to-one .

Models.py

class Profile(models.Model):
  user = models.OneToOneField(User, on_delete=models.CASCADE,  null=True)
  profile_picture = models.ImageField(upload_to='customer_profile_images/%Y/%m/%d/', null=True, blank=True, verbose_name="Profile Picture")
  phone_number = models.CharField(null=True, blank=True, max_length=10)

  # no need for following two methods
  # def create_user_profile(sender, instance, created, **kwargs):
    # if created:
        # Profile.objects.get_or_create(user=instance)

  # post_save.connect(create_user_profile, sender=User)

  def __str__(self):
     return f'{self.user.first_name} {self.user.last_name}'

В admin.py Я зарегистрировал модель профиля следующим образом:

from myapp import Profile


class ProfileAdmin(admin.ModelAdmin):
list_display = ('user', 'phone_number')

admin.site.register(Profile, ProfileAdmin)

И модель профиля успешно создается в модели пользователя.

И во время создания новой учетной записи для пользователя в views.py

class CustomerSignUpView(View):
def post(self, request):
    name_r = request.POST.get('customer_username')
    password_r = request.POST.get('customer_password')
    email_r = request.POST.get('customer_email')
    contact_number_r = request.POST.get('customer_contact_number')
    profile_picture_r = request.FILES['customer_profile_picture']

     # this is how i am saving contact number, profile picture for Profile model.

    if checkemail(email_r):
        c = User.objects.create_user(username=name_r, password=password_r, email=email_r)
        c.save()

        # add the following code
        p = Profile(user=c, phone_number=contact_number_r, profile_picture=profile_picture_r)
        p.save()       

        return render(request, 'catalog/customer_login.html')
    else:
        return render(request, 'catalog/customer_signup.html')

def get(self, request):
    return render(request, 'catalog/customer_signup.html')

Однако при создании новой учетной записи пользователя на странице регистрации я сталкиваюсь со следующей ошибкой:

error

Я не понимаю, как сохранить эти вновь созданные поля модели профиля с помощью метода save ().

ОБНОВЛЕНИЕ: Решение найдено -

В views.py, это как я сохраняю поля внутри модели профиля

     p = Profile(user=c, phone_number=contact_number_r, profile_picture=profile_picture_r)
     p.save()

Итеперь, когда я регистрирую нового пользователя, имя пользователя, изображение профиля и номер телефона добавляются также в модель профиля и даже во время удаления.нг / обновление данных профиля Изменения отражены как в модели пользователя, так и в модели профиля

Следующая ссылка полезна для требований моего проекта:

http://books.agiliq.com/projects/django-orm-cookbook/en/latest/one_to_one.html

1 Ответ

0 голосов
/ 11 декабря 2018

Прежде всего, нет необходимости сохранять экземпляр профиля после сохранения пользователя:

 @receiver(post_save, sender=User)
  def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

удалить вышеуказанный код.Чтобы ответить на ваш вопрос, если пользовательский экземпляр не создан, вы не хотите создавать экземпляр профиля, поэтому вам не нужно беспокоиться об этом.Пожалуйста, добавьте приведенный ниже код в admin.py , чтобы объединить форму администратора с профилем 1.

class ProfileInline(admin.StackedInline):    
    model = Profile
    can_delete = False
    verbose_name_plural = 'Profile'
    fk_name = 'user'

Кроме того, мы предлагаем прочитать this .

Вы не должны получать значения непосредственно из поста.Это не безопасный способ.Либо используйте базовую форму и получайте данные из словаря cleaned_data, либо используйте ModelForm.

Я предполагаю, что вы новичок в Django и, если вы не слишком одержимы использованием представления на основе классов, предложили бы использовать функциюна основе.Это будет легко для вас, вы увидите все шаги.

Следуйте этому одному.Если нет , это решит вашу проблему, поэтому вы можете настроить свой код на этот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...