Django: Assigning ForeignKey - Unable to get repr for class

2024/10/3 19:13:13

I ask this question here because, in my searches, this error has been generally related to queries rather than ForeignKey assignment.

The error I am getting occurs in a method of a model. Here is the code:

class Deal(models.Model):...model_fields...def _update_existing_deal(self, deal_dict):#deal made from deal_dict here, psuedo code belowdeal = Deal(deal_dict)HistoricalDeal().create_historical_deal(deal)self.price = deal_dict.get('price', self.price)if self.comment != deal_dict.get['comment']:self.comment = deal_dict.get('comment', '')self.set_unit_price()logger.debug('Existing deal, (pk: %d), updated.',self.pk)class HistoricalDeal(models.Model):deal = models.ForeignKey(Deal)created_at = models.DateTimeField(auto_now_add=True)price = models.DecimalField(max_digits=8, decimal_places=2, blank=True,default=0)unit_price = models.DecimalField(decimal_places=2, max_digits=6,null=True, blank=True)def create_historical_deal(self, deal):self.deal = dealself.price = deal.priceself.unit_price = deal.unit_priceself.save()logger.debug('HistoricalDeal created for Deal with pk: %d.',deal.pk)def __str__(self):return ', '.join([self.deal.name, self.created_at.date()])

The thing is, the Deal I am passing to HistoricalDeal.create_historical_deal is legit. Here's a picture of the debugger in PyCharm. Debugger Message

For search engines, the message there is:

Unable to get repr for <class 'deals.models.HistoricalDeal'>

Any ideas?

Edit: Full code for Deal below:

class Deal(models.Model):LUMBER = 'lumber'WOODBLANK = 'woodblank'DOWEL = 'dowel'VENEER = 'veneer'PLYWOOD = 'plywood'TYPE_CHOICES = ((LUMBER, 'Lumber'),(WOODBLANK, 'Wood Blank'),(DOWEL, 'Dowel'),(VENEER, 'Veneer'),(PLYWOOD, 'Plywood'),)# define the correct method and unit for each material type# mainly used in `get_unit_price`MATERIAL_MAPPING = {LUMBER: {'method': lambda self: float(self.price) / (float(self.board_feet) or 1),'unit': 'BF',},WOODBLANK: {'method': lambda self: self.price,'unit': 'Purchase',},DOWEL: {'method': lambda self: float(self.price) / (float(self.linear_feet) or 1),'unit': 'LF',},VENEER: {'method': lambda self: float(self.price) / (float(self.square_feet) or 1),'unit': 'SF',},PLYWOOD: {'method': lambda self: float(self.price) / (float(self.square_feet) or 1),'unit': 'SF',}}name = models.CharField(max_length=200)slug = models.SlugField(max_length=100)url = models.CharField(max_length=200, blank=True)vendor = models.ForeignKey('Vendor')category = models.ForeignKey('Category')active = models.BooleanField(default=True)created_at = models.DateTimeField(auto_now_add=True)updated_at = models.DateTimeField(auto_now=True)price = models.DecimalField(max_digits=8, decimal_places=2, blank=True,default=0)comment = models.TextField(blank=True)img = models.ImageField(blank=True)unique_lot = models.IntegerField(default=None, blank=True, null=True)material_type = models.CharField(max_length=9, choices=TYPE_CHOICES)# attributes specific to material typesboard_feet = models.DecimalField(decimal_places=2, max_digits=6,null=True, blank=True)thickness = models.CharField(max_length=15,null=True, blank=True)length = models.CharField(max_length=15,null=True, blank=True)width = models.CharField(max_length=15,null=True, blank=True)diameter = models.CharField(max_length=15,null=True, blank=True)linear_feet = models.DecimalField(decimal_places=2, max_digits=6,null=True, blank=True)square_feet = models.DecimalField(decimal_places=2, max_digits=6,null=True, blank=True)adhesive_backing = models.NullBooleanField(default=False,null=True, blank=True)image = models.ForeignKey('Image', null=True, blank=True)unit_price = models.DecimalField(decimal_places=2, max_digits=6,null=True, blank=True)def set_unit_price(self):method = self.MATERIAL_MAPPING[self.material_type]['method']self.unit_price = method(self)self.save()@propertydef get_unit_price(self):method = self.MATERIAL_MAPPING[self.material_type]['method']unit = self.MATERIAL_MAPPING[self.material_type]['unit']return {'value': method(self),'units': unit}@classmethoddef _find_matching_deal(cls, deal_dict):""" Check for an existing deal that matches `deal_dict` """# TODO: use get_or_create?match = cls.objects.filter(material_type=deal_dict.get('deal_type', None),board_feet=deal_dict.get('boardfeet', None),thickness=deal_dict.get('thickness', None),length=deal_dict.get('length', None),width=deal_dict.get('width', None),diameter=deal_dict.get('diameter', None),linear_feet=deal_dict.get('linear_feet', None),square_feet=deal_dict.get('square_feet', None),adhesive_backing=deal_dict.get('adhesive_backing', None),unique_lot=deal_dict.get('unique_lot', None),category=deal_dict['category'],url=deal_dict['url'])if not match:return None# Because of the unique constraint, there should only be one matchassert len(match) == 1return match[0]@staticmethoddef _guess_category(name, url):""" Find the category that best matches the deal name/url """name = name.lower()url = url.lower()# create a string of unique possible name variantssearch_string = '|'.join({name,name.replace(' ', ''),name.replace('_', ' '),name.replace('-', ' '),name.replace('_', ''),name.replace('-', ''),url.replace(' ', ''),url.replace('-', ' '),url.replace('_', ' '),url.replace('-', ''),url.replace('_', ''),})# TODO: cache categories, don't query each timeall_categories = Category.objects.all()# get a list of categories that might matchmatching_categories = [category for category in all_categoriesif category.name.lower() in search_string]logger.debug('Found these category matches for %s: %s', name,matching_categories)if len(matching_categories) == 0:matching_categories = [category for category in all_categoriesif category.name.replace(' ', '').lower() in search_string]if len(matching_categories) == 0:# add it to the Misc categoryreturn Category.objects.get_or_create(name="Miscellaneous",defaults={'slug': 'misc'})[0]# return the first matchreturn matching_categories[0]@staticmethoddef _get_vendor(vendor_name):return Vendor.objects.get_or_create(name=vendor_name,defaults={'shipping': False})[0]@staticmethoddef _capitalize_name(name):return name.replace('-', ' ').replace('_', ' ').title()def _update_existing_deal(self, deal_dict):self.price = deal_dict.get('price', self.price)if self.comment != deal_dict.get['comment']:self.comment = deal_dict.get('comment', '')self.set_unit_price()logger.debug('Existing deal, (pk: %d), updated.',self.pk)@classmethoddef save_from_dict(cls, deal_dict):logger.debug('saving deal from dict: %s', deal_dict)deal_dict['category'] = cls._guess_category(deal_dict['name'], deal_dict['url'])deal_dict['name'] = cls._capitalize_name(deal_dict['name'])existing_deal = cls._find_matching_deal(deal_dict)if not existing_deal:logger.debug('This is a new deal, saving it')current_deal = cls.objects.create(name=deal_dict.get('name'),slug=deal_dict.get('slug', ''),url=deal_dict.get('url'),image=Image.from_url(deal_dict.get('image_url', None)),price=deal_dict.get('price'),comment=''.join(deal_dict.get('comment', [])),material_type=deal_dict.get('deal_type', None),board_feet=deal_dict.get('boardfeet', None),thickness=deal_dict.get('thickness', None),length=deal_dict.get('length', None),width=deal_dict.get('width', None),diameter=deal_dict.get('diameter', None),linear_feet=deal_dict.get('linear_feet', None),square_feet=deal_dict.get('square_feet', None),adhesive_backing=deal_dict.get('adhesive_backing', None),unique_lot=deal_dict.get('unique_lot', None),category=deal_dict['category'],vendor=cls._get_vendor(deal_dict['vendor_name']),)current_deal.set_unit_price()else:logger.debug('Existing deal, updating it (pk: %d)',existing_deal.pk)HistoricalDeal().create_historical_deal(existing_deal)existing_deal._update_existing_deal(deal_dict)def __str__(self):return '<Deal: %d, %s>' % (self.pk, self.name)class Meta(object):unique_together = (('material_type','board_feet','thickness','length','width','diameter','linear_feet','square_feet','adhesive_backing','unique_lot','category','url'),)
Answer

The solution was pointed out by James Bennet's comment on the answer from Sandwich Heat:

In the HistoricalDeal model's __str__ method, I passed a date object to ''.join([...]) (which is not a string). Simply coercing that value into a string with str() eliminated the problem.

https://en.xdnf.cn/q/70699.html

Related Q&A

Counting day-of-week-hour pairs between two dates

Consider the following list of day-of-week-hour pairs in 24H format:{Mon: [9,23],Thu: [12, 13, 14],Tue: [11, 12, 14],Wed: [11, 12, 13, 14]Fri: [13],Sat: [],Sun: [], }and two time points, e.g.:Start:dat…

Download A Single File Using Multiple Threads

Im trying to create a Download Manager for Linux that lets me download one single file using multiple threads. This is what Im trying to do : Divide the file to be downloaded into different parts by sp…

Merge string tensors in TensorFlow

I work with a lot of dtype="str" data. Ive been trying to build a simple graph as in https://www.tensorflow.org/versions/master/api_docs/python/train.html#SummaryWriter. For a simple operat…

How to reduce memory usage of threaded python code?

I wrote about 50 classes that I use to connect and work with websites using mechanize and threading. They all work concurrently, but they dont depend on each other. So that means 1 class - 1 website - …

Connection is closed when a SQLAlchemy event triggers a Celery task

When one of my unit tests deletes a SQLAlchemy object, the object triggers an after_delete event which triggers a Celery task to delete a file from the drive.The task is CELERY_ALWAYS_EAGER = True when…

Python escape sequence \N{name} not working as per definition

I am trying to print unicode characters given their name as follows:# -*- coding: utf-8 -*- print "\N{SOLIDUS}" print "\N{BLACK SPADE SUIT}"However the output I get is not very enco…

Binary integer programming with PULP using vector syntax for variables?

New to the python library PULP and Im finding the documentation somewhat unhelpful, as it does not include examples using lists of variables. Ive tried to create an absolutely minimalist example below …

Nonblocking Scrapy pipeline to database

I have a web scraper in Scrapy that gets data items. I want to asynchronously insert them into a database as well. For example, I have a transaction that inserts some items into my db using SQLAlchemy …

python function to return javascript date.getTime()

Im attempting to create a simple python function which will return the same value as javascript new Date().getTime() method. As written here, javascript getTime() method returns number of milliseconds …

Pulling MS access tables and putting them in data frames in python

I have tried many different things to pull the data from Access and put it into a neat data frame. right now my code looks like this.from pandas import DataFrame import numpy as npimport pyodbc from sq…