Django 2.2 user = models.ForeignKey (пользователь, null = True, пусто = True) TypeError: __init __ () отсутствует 1 обязательный позиционный аргумент: 'on_delete' - PullRequest
0 голосов
/ 24 мая 2019

Я пытаюсь создать пользовательский объект в своем классе Cart в моем файле models.py. И я получаю следующая ошибка:

user        = models.ForeignKey(User, null=True, blank=True)
TypeError: __init__() missing 1 required positional argument: 'on_delete'

Можете ли вы помочь мне правильно добавить требуемый позиционный аргумент: on_delete в oder, чтобы позже использовать объект пользователя при создании сеанса корзины?

Заранее спасибо.

В моем приложении "Тележки для тележек" у меня есть следующий код:

from django.conf import settings 

from django.db import models
from django.db.models.signals import pre_save, post_save, m2m_changed

from products.models import Product


User = settings.AUTH_USER_MODEL

class CartManager(models.Manager):
    def new_or_get(self, request):
        cart_id = request.session.get("cart_id", None)
        qs = self.get_queryset().filter(id=cart_id)
        if qs.count() == 1:
            new_obj = False
            cart_obj = qs.first()
            if request.user.is_authenticated and cart_obj.user is None:
                cart_obj.user = request.user
                cart_obj.save()
        else:
            cart_obj = Cart.objects.new(user=request.user)
            new_obj = True  
            request.session['card_id'] = cart_obj.id
        return cart_obj, new_obj

    def new(self, user=None):
        user_obj = None
        if user is not None:
            if user.is_authenticated:
                user_obj = user
        return self.model.objects.create(user=user_obj)


class Cart(models.Model):
    user        = models.ForeignKey(User, null=True, blank=True)
    products    = models.ManyToManyField(Product, blank=True)
    subtotal    = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)
    total       = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)
    updated     = models.DateTimeField(auto_now=True)
    timestamp   = models.DateTimeField(auto_now_add=True)

    objects = CartManager()

    def __str__(self):
        return str(self.id)


def m2m_changed_cart_receiver(sender, instance, action, *args, **kwargs):
    if action == 'post_add' or action == 'post_remove' or action == 'post_clear':
        products = instance.products.all()
        total = 0
        for x in products:
            total += x.price
        if instance.subtotal !=total: 
            instance.subtotal = total
            instance.save()

m2m_changed.connect(m2m_changed_cart_receiver, sender=Cart.products.through)

def pre_save_cart_receiver(sender, instance, *args, **kwargs):
    if instance.subtotal > 0:
        instance.total = instance.subtotal 
    else:
        instance.total = 0.00

pre_save.connect(pre_save_cart_receiver, sender=Cart)




   Thanks,

Ответы [ 2 ]

1 голос
/ 24 мая 2019

Вам не хватает одного обязательного аргумента в поле пользователя, необходимого в ForeignKey

, вы можете добавить это

on_delete=models.SET_NULL

или

on_delete=models.CASCADE

, затем полебудет

user = models.ForeignKey(User, null=True, related_name="author",
    on_delete=models.SET_NULL)

или

user = models.ForeignKey(User, null=True, blank=True,
    on_delete=models.CASCADE)

. Более подробную информацию о параметре on_delete можно получить по адресу официальные документы ссылка

1 голос
/ 24 мая 2019

При работе с классом ForeignKey параметр on_delete требуется в __init__.(Должно быть установлено явно) в Django (например, 2.0).Это не требовалось в Django (1,8).

from django.conf import settings 
from django.db import models
from django.db.models.signals import pre_save, post_save, m2m_changed

from products.models import Product


User = settings.AUTH_USER_MODEL

class CartManager(models.Manager):
    def new_or_get(self, request):
        cart_id = request.session.get("cart_id", None)
        qs = self.get_queryset().filter(id=cart_id)
        if qs.count() == 1:
            new_obj = False
            cart_obj = qs.first()
            if request.user.is_authenticated and cart_obj.user is None:
                cart_obj.user = request.user
                cart_obj.save()
        else:
            cart_obj = Cart.objects.new(user=request.user)
            new_obj = True  
            request.session['card_id'] = cart_obj.id
        return cart_obj, new_obj

    def new(self, user=None):
        user_obj = None
        if user is not None:
            if user.is_authenticated:
                user_obj = user
        return self.model.objects.create(user=user_obj)


class Cart(models.Model):
    user        = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE) # You should add on_delete=models.CASCADE argument
    products    = models.ManyToManyField(Product, blank=True)
    subtotal    = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)
    total       = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)
    updated     = models.DateTimeField(auto_now=True)
    timestamp   = models.DateTimeField(auto_now_add=True)

    objects = CartManager()

    def __str__(self):
        return str(self.id)


def m2m_changed_cart_receiver(sender, instance, action, *args, **kwargs):
    if action == 'post_add' or action == 'post_remove' or action == 'post_clear':
        products = instance.products.all()
        total = 0
        for x in products:
            total += x.price
        if instance.subtotal !=total: 
            instance.subtotal = total
            instance.save()

m2m_changed.connect(m2m_changed_cart_receiver, sender=Cart.products.through)

def pre_save_cart_receiver(sender, instance, *args, **kwargs):
    if instance.subtotal > 0:
        instance.total = instance.subtotal 
    else:
        instance.total = 0.00

pre_save.connect(pre_save_cart_receiver, sender=Cart)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...