Мне нужно обновлять мою таблицу каждый раз, когда вводится новое значение «sku» (не для создания новой записи), но это должно произойти, только если выбранный «клиент» совпадает.Если «клиент» отличается, то модель должна добавить новый объект с тем же «sku», но с разными «клиентами».
Один пользователь StackOverflow дал мне решение:
class ProductList(models.Model):
id_new = models.IntegerField(primary_key=True)
sku = models.CharField(primary_key=False, max_length=200)
client = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
name = models.CharField(max_length=256)
description = models.CharField(max_length=1000)
storage = models.CharField(max_length=256)
cost_price = models.CharField(max_length=256)
sell_price = models.CharField(max_length=256)
ncm = models.CharField(max_length=256)
inventory = models.IntegerField(null=True)
class Meta:
unique_together = (('sku', 'client'),)
def save(self, *args, **kwargs):
if self.pk:
current_instance = self.__class__.objects.get(pk=self.pk)
if current_instance.client != self.client:
self.pk = None
return super(ProductList, self).save(*args, **kwargs)
После того, как я добавил функцию сохранения, проблема была решена.Однако, если я пытаюсь обновить существующую таблицу, я получаю следующую проблему для каждого поля в моем файле:
Line number: 1 - get() returned more than one ProductList -- it returned 2!
345, Teste 1, Descrição 1, 87654, 59,99, 180, 65, 884, 25
Traceback (most recent call last):
File "/home/checkstore/.local/lib/python3.6/site-packages/import_export/resources.py", line 453, in import_row
instance, new = self.get_or_init_instance(instance_loader, row)
File "/home/checkstore/.local/lib/python3.6/site-packages/import_export/resources.py", line 267, in get_or_init_instance
instance = self.get_instance(instance_loader, row)
File "/home/checkstore/.local/lib/python3.6/site-packages/import_export/resources.py", line 261, in get_instance
return instance_loader.get_instance(row)
File "/home/checkstore/.local/lib/python3.6/site-packages/import_export/instance_loaders.py", line 33, in get_instance
return self.get_queryset().get(**params)
File "/home/checkstore/.local/lib/python3.6/site-packages/django/db/models/query.py", line 403, in get
(self.model._meta.object_name, num)
Clientes.models.ProductList.MultipleObjectsReturned: get() returned more than one ProductList -- it returned 2!
Мой файл admin.py представлен ниже:
from django.contrib import admin
from .forms import FaturaForm, ConfirmImportForm
from .models import (Token,
Sell,
LogisticCost,
IncomeCost,
FinalPayment,
CustomerServiceCost,
Fatura,
ProductList)
from import_export.admin import ImportExportModelAdmin, ImportMixin
from .resources import ProductListResource
from django.contrib.auth.models import User
try:
from django.utils.encoding import force_text
except ImportError:
from django.utils.encoding import force_unicode as force_text
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.template.response import TemplateResponse
from django.utils.translation import ugettext_lazy as _
class ProductAdminImport(ImportExportModelAdmin, ImportMixin):
resource_class = ProductListResource
list_display = ('sku', 'client', 'name', 'description', 'storage', 'cost_price', 'sell_price', 'ncm', 'inventory')
list_filter = ['client']
def process_import(self, request, *args, **kwargs):
"""
Perform the actual import action (after the user has confirmed the import)
"""
if not self.has_import_permission(request):
raise PermissionDenied
confirm_form = ConfirmImportForm(request.POST)
if confirm_form.is_valid():
import_formats = self.get_import_formats()
input_format = import_formats[
int(confirm_form.cleaned_data['input_format'])
]()
tmp_storage = self.get_tmp_storage_class()(name=confirm_form.cleaned_data['import_file_name'])
data = tmp_storage.read(input_format.get_read_mode())
if not input_format.is_binary() and self.from_encoding:
data = force_text(data, self.from_encoding)
dataset = input_format.create_dataset(data)
for i in User.objects.all():
if i.username == str(request.POST['original_file_name'].split('.')[0]):
dataset.append_col([i.id] * dataset.height, header='client')
result = self.process_dataset(dataset, confirm_form, request, *args, **kwargs)
tmp_storage.remove()
return self.process_result(result, request)
def import_action(self, request, *args, **kwargs):
'''
Perform a dry_run of the import to make sure the import will not
result in errors. If there where no error, save the user
uploaded file to a local temp file that will be used by
'process_import' for the actual import.
'''
if not self.has_import_permission(request):
raise PermissionDenied
resource = self.get_import_resource_class()(**self.get_import_resource_kwargs(request, *args, **kwargs))
context = self.get_import_context_data()
import_formats = self.get_import_formats()
form_type = self.get_import_form()
form = form_type(import_formats,
request.POST or None,
request.FILES or None)
if request.POST and form.is_valid():
input_format = import_formats[
int(form.cleaned_data['input_format'])
]()
import_file = form.cleaned_data['import_file']
# first always write the uploaded file to disk as it may be a
# memory file or else based on settings upload handlers
tmp_storage = self.write_to_tmp_storage(import_file, input_format)
# then read the file, using the proper format-specific mode
# warning, big files may exceed memory
try:
data = tmp_storage.read(input_format.get_read_mode())
if not input_format.is_binary() and self.from_encoding:
data = force_text(data, self.from_encoding)
dataset = input_format.create_dataset(data)
except UnicodeDecodeError as e:
return HttpResponse(_(u"<h1>Imported file has a wrong encoding: %s</h1>" % e))
except Exception as e:
return HttpResponse(
_(u"<h1>%s encountered while trying to read file: %s</h1>" % (type(e).__name__, import_file.name)))
# if str(request.user.username) == str(import_file.name.split('.')[0]):
for i in User.objects.all():
csv_client_name = str(import_file.name.split('.')[0])
if i.username == csv_client_name:
dataset.append_col([i.id] * dataset.height, header='client')
result = resource.import_data(dataset, dry_run=True,
raise_errors=False,
file_name=import_file.name,
user=request.user)
context['result'] = result
if not result.has_errors():
context['confirm_form'] = ConfirmImportForm(initial={
'import_file_name': tmp_storage.name,
'original_file_name': import_file.name,
'input_format': form.cleaned_data['input_format'],
})
context.update(self.admin_site.each_context(request))
context['title'] = _("Import")
context['form'] = form
context['opts'] = self.model._meta
context['fields'] = [f.column_name for f in resource.get_user_visible_fields()]
request.current_app = self.admin_site.name
return TemplateResponse(request, [self.import_template_name],
context)
class FaturaModel(admin.ModelAdmin):
form = FaturaForm
list_filter = ['cliente', 'pago']
list_display = ('cliente',
'id',
'dia',
'numero_da_fatura',
'mes',
'ano',
'valor',
'pago')
class SellsAdmin(admin.ModelAdmin):
list_filter = ['client']
list_display = ['client', 'date']
admin.site.register(Token)
admin.site.register(Sell, SellsAdmin)
admin.site.register(LogisticCost)
admin.site.register(IncomeCost)
admin.site.register(FinalPayment)
admin.site.register(CustomerServiceCost)
admin.site.register(Fatura, FaturaModel)
admin.site.register(ProductList, ProductAdminImport)