Джанго Формы и Модели - PullRequest
       7

Джанго Формы и Модели

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

У меня есть представление на основе функций:

@login_required
def profile(request):
if request.method == 'POST':
    form = IngredientForm(request.POST, user=request.user)
    if form.is_valid():
        form.save()
        ingredient_1 = form.cleaned_data['ingredient_1']
        ingredient_2 = form.cleaned_data['ingredient_2']
        ingredient_3 = form.cleaned_data['ingredient_3']
        ingredient_4 = form.cleaned_data['ingredient_4']
        ingredient_5 = form.cleaned_data['ingredient_5']
        messages.success(request, f'Ingredients added to your account!')
        return redirect('profile')
else:
    form = IngredientForm(user=request.user)
return render(request, 'users/profile.html', {'form': form})

, а модель:

from django.db import models
from django.contrib.auth.models import User

class ingredients(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
ingredient_1 = models.CharField(max_length=32)
ingredient_2 = models.CharField(max_length=32)
ingredient_3 = models.CharField(max_length=32)
ingredient_4 = models.CharField(max_length=32)
ingredient_5 = models.CharField(max_length=32)

forms.py выглядит так:

class IngredientForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
    self.user = kwargs.pop('user', None)
    super(IngredientForm, self).__init__(*args, **kwargs)
class Meta:
    model = ingredients
    fields = ('ingredient_1', 'ingredient_2', 'ingredient_3', 'ingredient_4', 'ingredient_5')

Япытаюсь найти текущего пользователя и использовать его в качестве ключа для таблицы ингредиентов в моей базе данных.Я не уверен, как получить текущего пользователя и установить пользователя в таблице в качестве текущего пользователя.Буду признателен за любую помощь:)

Ошибка, которую я получаю при отправке формы: enter image description here

Ответы [ 2 ]

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

Вы экономите неправильно. ModelForm сама получает заявленные данные из формы и сохраняет их.В вашем случае вам просто нужно добавить пользователя в поле «один к одному»:

@login_required
def profile(request):    
    if request.method == 'POST':
        form = IngredientForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.user = request.user
            obj.save()
            messages.success(request, f'Ingredients added to your account!')
            return redirect('profile')
    else:
        form = IngredientForm(user=request.user)
    return render(request, 'users/profile.html', {'form': form})

и добавить пользователя в поле ModelForm:

class IngredientForm(forms.ModelForm):

    class Meta:
        model = ingredients
        fields = __all__

Длясоздание профиля и слияние с пользователем на странице администратора следуют за моим другим ответом, который просто указывает, что: https://stackoverflow.com/a/53718908/7470786

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

Пользовательское поле в ингредиентах является первичным ключом, поэтому оно имеет ненулевое ограничение.В тот момент, когда вы вызываете form.save(), django пытается создать новый экземпляр компонентов из данных, привязанных к форме, и пользователь не привязан к нему, поэтому происходит сбой, потому что он не может создать новый экземпляр с user = None.Должно работать следующее:

instance = form.save(commit=False)
instance.user = request.user 
instance.save()

Кроме того, вы можете перезаписать метод сохранения формы.

Редактировать: Теперь я понимаю (я думаю), что вы хотите сделать.Вы хотите расширить модель пользователя с помощью «профиля пользователя».Вот как вы это сделаете: настройте модель ингредиентов по следующей модели UserIngredients (я удаляю аргумент primary_key и добавляю related_name):

class UserIngredients(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='ingredients')
    ingredient_1 = models.CharField(max_length=32)
    ...

Вы можете связать создание / обновление экземпляра User с созданием/ обновить экземпляр UserIngredients с помощью сигналов следующим образом: нам нужен один импорт:

from django.dispatch import receiver

Затем добавьте в файл модели следующее:

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserIngredients.objects.create(user=instance)

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

В конце опустите перезапись__init__ в IngredientForm и настройте метод вашего профиля:

form = IngredientForm(request.POST)
if form.is_valid():
    instance = form.save(commit=False)
    instance.user = request.user
    instance.save()
    messages.success(request, f'Ingredients added to your account!')
    return redirect('profile')
...