[英]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.