繁体   English   中英

无法在 model 上为一对多关系添加任何数据 model 相关名称和 Django 信号问题

[英]Cant add any data on model for One to Many relationship model related_name and Django signal issue

我无法将任何 object 添加到我的客户 Model 以解决相关名称问题。 我有 4 个或更多型号,并且我已使用 Django 信号进行 model 自动更新。 Customer Model 和Ordered的 model 关系与外键。 我在Ordered Model 上使用了related_name关键字(请参阅详细模型信息)。 因此,当我在我的客户上创建任何对象/实例或订购 model 时,我无法在我的客户或 Ordered 上添加任何 object 或实例。 我发现问题和related_name 问题。 我想在订购的 model 上保留相关名称。 但无法解决。

    Environment:
    Request Method: POST
    Request URL: http://127.0.0.1:8000/admin/accounts_app/customer/add/
    Django Version: 3.0.6
    Python Version: 3.8.2
    Installed Applications:
    ['django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'users_app.apps.UsersAppConfig',
     'accounts_app.apps.AccountsAppConfig',
     'rest_framework']
    Installed Middleware:
    ['django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware']
    Traceback (most recent call last):
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
        response = get_response(request)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
        response = self.process_exception_by_middleware(e, request)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
        response = wrapped_callback(request, *callback_args, **callback_kwargs)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 607, in wrapper
        return self.admin_site.admin_view(view)(*args, **kwargs)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
        response = view_func(request, *args, **kwargs)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
        response = view_func(request, *args, **kwargs)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 231, in inner
        return view(request, *args, **kwargs)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1638, in add_view
        return self.changeform_view(request, None, form_url, extra_context)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
        return bound_method(*args, **kwargs)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
        response = view_func(request, *args, **kwargs)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1522, in changeform_view
        return self._changeform_view(request, object_id, form_url, extra_context)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1565, in _changeform_view
        self.save_model(request, new_object, form, not add)
      File "/home/asad/PycharmProjects/microshop/venv/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1081, in save_model
        obj.save()
      File "/home/asad/PycharmProjects/microshop/accounts_app/models/account.py", line 31, in save
        account.save()
      File "/home/asad/PycharmProjects/microshop/accounts_app/models/account.py", line 54, in save
        self.unpaid_money = sum([item.unpaid_money for item in self.customer.ordered_set.all()])
    Exception Type: AttributeError at /admin/accounts_app/customer/add/
    Exception Value: 'Customer' object has no attribute 'ordered_set'

客户模型

    class Customer(models.Model):
        """
        Customer Model
        """
        name = models.CharField("Name", max_length=100)
        phone_number = models.CharField("Mobile Number", max_length=100)
        address = models.TextField(blank=True, null=True)
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)

        def __str__(self):
            return "Customer: %s" % self.name

        def save(self, *args, **kwargs):
            """
            Create a new Account model object instance while created a new customer at Cutomer Table.
            """
            is_new = True if not self.id else False
            super(Customer, self).save(*args, **kwargs)
            if is_new:
                account = Account(customer=self)
                account.save()

账户模型

    class Account(models.Model):
        """
        Customer Account. One customer has only an account. This Table dont taken any input.
        It will be updated automatic.
        This table records customer paid or unpaid for alltime.
        """
        customer = models.OneToOneField(Customer, on_delete=models.CASCADE, primary_key=True)
        paid_money = models.FloatField(blank=True, null=True)
        unpaid_money = models.FloatField(blank=True, null=True)
        paid_status = models.BooleanField(default=False)
        customer_credit = models.FloatField(blank=True, null=True)
        customer_debit = models.FloatField(blank=True, null=True)
        extra_info = models.TextField(blank=True, null=True)
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)

        def __str__(self):
            return "Account Holder: %s" % self.customer.name

        def save(self, *args, **kwargs):
            self.unpaid_money = sum([item.unpaid_money for item in self.customer.ordered_set.all()])
            self.paid_money = sum([item.customer_paid for item in self.customer.ordered_set.all()])
            self.customer_credit = sum([x.customer_credit for x in self.customerdebitcredit_set.all()]) + self.paid_money
            self.customer_debit = sum([x.customer_debit for x in self.customerdebitcredit_set.all()]) + self.unpaid_money
            if self.customer_credit < self.customer_debit:
                self.paid_status = False
            elif self.customer_credit >= self.customer_debit:
                self.paid_status = True

            super().save(*args, **kwargs)

已订购 Model

class Ordered(models.Model):
    """
    Order Model of each customer. Customer has taken many orders and pay any amount or unpaid.
    """
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='order_items')
    product_name = models.CharField(max_length=100)
    product_price = models.FloatField()
    customer_paid = models.FloatField(default=0)
    paid_status = models.BooleanField(blank=True)
    unpaid_money = models.FloatField(blank=True)
    order_custom_date = models.DateTimeField(blank=True, null=True)
    extra_info = models.TextField(blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return "%s price: %s TK, Paid: %s TK Unpaid %s" % (self.product_name, self.product_price, self.customer_paid, self.unpaid_money)

    def save(self, *args, **kwargs):
        if self.product_price == self.customer_paid:
            self.paid_status = True
            self.unpaid_money = 0
        elif self.product_price > self.customer_paid:
            self.paid_status = False
            self.unpaid_money = self.product_price - self.customer_paid

        if self.customer_paid > self.product_price:
            raise ValueError("Not allowed. Customer paid too much!")

        super().save(*args, **kwargs)


@receiver(post_save, sender=Ordered)
def order_saved(sender, instance, created=False, **kwargs):
    if created:
        instance.customer.account.extra_info = "f"
        instance.customer.account.save()

Django 信号处理问题和 model realted_name 问题。 但是如何将解决方案与问题联系起来?

让我们试试下面的代码

  from django.db.models import Sum

  ...
  self.unpaid_money = self.customer.order_items.aggregate(total_unpaid=Sum('unpaid_money'))['total_unpaid'] or 0

我的建议,尽可能从 SQL function 计算,这将提高您的应用程序性能

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM