I encountered a strange behavior while applying a signal to a new model, I'm not sure to understand what is wrong but it seems related with the fact that I used abstract classes.
The models (simplified)
Basically, I have Article, Photo (inheriting from Post)
class Post(models.Model):
class Meta:
abstract = True
some_field = models.Something()
class Article(Post):
category = models.ForeignKey(Article_category, null=True, on_delete=models.SET_NULL)
some_field = models.Something()
class Photo(Post):
category = models.ForeignKey(Photo_category, null=True, on_delete=models.SET_NULL)
some_field = models.Something()
and their respective Categories
class Category(models.Model):
class Meta:
abstract = True
parent = models.ForeignKey('self', null=True, blank=True, related_name='nested_category', on_delete=models.SET_NULL)
name = models.CharField(max_length=50)
count = models.PositiveSmallIntegerField(default=0, editable=False)
class Article_category(Category):
#classmethod
def load(cls):
cache.set('{}'.format(cls.__name__), cls.objects.all())
class Photo_category(Category):
#classmethod
def load(cls):
cache.set('{}'.format(cls.__name__), cls.objects.all())
The signal
A straighforward incremental counter. Every time an article/photo is created, it's corresponding category count is updated and the entire model is saved in the cache (for templating purposes)
from django.db.models import F
#receiver(post_save, sender=Article) ----> here comes trouble
#receiver(post_save, sender=Photo)
def add_one_to_count(sender, instance, **kwargs):
cat = type(instance.category).objects.get(name=instance.category)
cat.count = F('count')+1
cat.save()
cache.set('{}_category'.format(sender.__name__), type(instance.category).objects.all())
The problem
What you saw above works like a charm for #receiver(post_save, sender=Photo) but when I add #receiver(post_save, sender=Article), DB initialization with fixture fails and I only get emptyset tables (mariaDB). This very line is the only one changing fail to success and I can't figure why. Since count is defined in the abstract class, I wondered whether it had something to do with it, for I did not have any issue applying a similar logic to categories:
# this works perfectly
#receiver(post_save, sender=Photo_category)
#receiver(post_delete, sender=Photo_category)
#receiver(post_save, sender=Article_category)
#receiver(post_delete, sender=Article_category)
def refresh_cached_category(sender, instance, using, **kwargs):
cache.set('{}'.format(type(instance).__name__), type(instance).objects.all())
Thanks for any enlightenment
The complete Traceback
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/loaddata.py", line 72, in handle
self.loaddata(fixture_labels)
File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/loaddata.py", line 114, in loaddata
self.load_label(fixture_label)
File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/loaddata.py", line 181, in load_label
obj.save(using=self.using)
File "/usr/local/lib/python3.7/site-packages/django/core/serializers/base.py", line 223, in save
models.Model.save_base(self.object, using=using, raw=True, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 790, in save_base
update_fields=update_fields, raw=raw, using=using,
File "/usr/local/lib/python3.7/site-packages/django/dispatch/dispatcher.py", line 175, in send
for receiver in self._live_receivers(sender)
File "/usr/local/lib/python3.7/site-packages/django/dispatch/dispatcher.py", line 175, in <listcomp>
for receiver in self._live_receivers(sender)
File "/usr/src/cms/website/observers.py", line 26, in add_one_to_count
cat = type(instance.category).objects.get(name=instance.category)
File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 408, in get
self.model._meta.object_name
website.models.DoesNotExist: Problem installing fixture '/usr/src/cms/../test/data_dev.yaml': Article_category matching query does not exist.
You can't filter on name=instance.category in your query, because that's not a str. You need to filter on name=instance.category.name but first you also need to make sure instance.category isn't None (since it can be).
The thing I don't understand is why you perform a query in the first place, just to fetch the same object: instance.category is the same as ArticleCategory.objects.get(name=instance.category.name) assuming the name is unique, except you do an extra query to the db.
Also the query will raise an exception if you have two categories with the same name (which you don't exclude in your model). So your code should be:
def add_one_to_count(sender, instance, **kwargs):
if instance.category:
instance.category.count = F('count')+1
instance.category.save()
cache.set('{}_category'.format(sender.__name__), type(instance.category).objects.all())
Related
When I'm trying to make migrations of my models in Django, I keep getting the same error, even after I've commented out all the changes:
(.venv) C:\Users\jezdo\venv\chat\chat_proj>python manage.py makemigrations chat
Migrations for 'chat':
chat\migrations\0002_alter_customusergroup_custom_group_name_and_more.py
- Alter field custom_group_name on customusergroup
- Alter field users on customusergroup
Traceback (most recent call last):
File "C:\Users\jezdo\.venv\chat\chat_proj\manage.py", line 22, in <module>
main()
File "C:\Users\jezdo\.venv\chat\chat_proj\manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "C:\Users\jezdo\.venv\lib\site-packages\django\core\management\__init__.py", line 446, in execute_from_command_line
utility.execute()
File "C:\Users\jezdo\.venv\lib\site-packages\django\core\management\__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\jezdo\.venv\lib\site-packages\django\core\management\base.py", line 402, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Users\jezdo\.venv\lib\site-packages\django\core\management\base.py", line 448, in execute
output = self.handle(*args, **options)
File "C:\Users\jezdo\.venv\lib\site-packages\django\core\management\base.py", line 96, in wrapped
res = handle_func(*args, **kwargs)
File "C:\Users\jezdo\.venv\lib\site-packages\django\core\management\commands\makemigrations.py", line 239, in handle
self.write_migration_files(changes)
File "C:\Users\jezdo\.venv\lib\site-packages\django\core\management\commands\makemigrations.py", line 278, in write_migration_files
migration_string = writer.as_string()
File "C:\Users\jezdo\.venv\lib\site-packages\django\db\migrations\writer.py", line 141, in as_string
operation_string, operation_imports = OperationWriter(operation).serialize()
File "C:\Users\jezdo\.venv\lib\site-packages\django\db\migrations\writer.py", line 99, in serialize
_write(arg_name, arg_value)
File "C:\Users\jezdo\.venv\lib\site-packages\django\db\migrations\writer.py", line 63, in _write
arg_string, arg_imports = MigrationWriter.serialize(_arg_value)
File "C:\Users\jezdo\.venv\lib\site-packages\django\db\migrations\writer.py", line 282, in serialize
return serializer_factory(value).serialize()
File "C:\Users\jezdo\.venv\lib\site-packages\django\db\migrations\serializer.py", line 221, in serialize
return self.serialize_deconstructed(path, args, kwargs)
File "C:\Users\jezdo\.venv\lib\site-packages\django\db\migrations\serializer.py", line 99, in serialize_deconstructed
arg_string, arg_imports = serializer_factory(arg).serialize()
File "C:\Users\jezdo\.venv\lib\site-packages\django\db\migrations\serializer.py", line 50, in serialize
item_string, item_imports = serializer_factory(item).serialize()
File "C:\Users\jezdo\.venv\lib\site-packages\django\db\migrations\serializer.py", line 50, in serialize
item_string, item_imports = serializer_factory(item).serialize()
File "C:\Users\jezdo\.venv\lib\site-packages\django\db\migrations\serializer.py", line 386, in serializer_factory
raise ValueError(
ValueError: Cannot serialize: <User: jezdo>
There are some values Django cannot serialize into migration files.
For more, see https://docs.djangoproject.com/en/4.1/topics/migrations/#migration-serializing
my model in models.py:
class CustomUserGroup(models.Model):
custom_group_name = models.CharField(max_length=50, unique=True)
users= MultiSelectField(max_length=100,choices=users_list,unique=False)
class Meta:
verbose_name_plural = 'Custom Groups'
ordering = ['custom_group_name']
def __unicode__(self):
return self.custom_group_name
I wanted to create another model similar to CustomUserGroup byt with a different "users" field:
class CustomUserGroup2(models.Model):
custom_group_name = models.CharField(max_length=50, unique=True)
users= models.ManyToManyField(User)
class Meta:
verbose_name_plural = 'Custom Groups'
ordering = ['custom_group_name']
def __unicode__(self):
return self.custom_group_name
but couldn't makemigrations due to the described error. Now I cannot make any migrations whatsoever, even after having deleted the CustomUserGroup2 class.
I'm using Python 3.10.4 and Django 4.1.6.
When attempting to migrate my database in Django. I receive the following:
Running migrations:
Applying shop.0002_transactions...Traceback (most recent call last):
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/parler/models.py", line 942, in contribute_translations
base = shared_model._parler_meta
AttributeError: type object 'Product' has no attribute '_parler_meta'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/core/management/base.py", line 328, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/core/management/base.py", line 369, in execute
output = self.handle(*args, **options)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 233, in handle
fake_initial=fake_initial,
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/executor.py", line 117, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/executor.py", line 245, in apply_migration
state = migration.apply(state, schema_editor)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/migration.py", line 114, in apply
operation.state_forwards(self.app_label, project_state)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/operations/models.py", line 86, in state_forwards
list(self.managers),
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/state.py", line 96, in add_model
self.reload_model(app_label, model_name)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/state.py", line 157, in reload_model
self._reload(related_models)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/state.py", line 190, in _reload
self.apps.render_multiple(states_to_be_rendered)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/state.py", line 307, in render_multiple
model.render(self)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/state.py", line 578, in render
return type(self.name, bases, body)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/models/base.py", line 320, in __new__
new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/migrations/state.py", line 338, in register_model
self.do_pending_operations(model)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/apps/registry.py", line 424, in do_pending_operations
function(model)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/apps/registry.py", line 403, in apply_next_model
self.lazy_model_operation(next_function, *more_models)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/apps/registry.py", line 389, in lazy_model_operation
function()
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/models/fields/related.py", line 317, in resolve_related_class
field.do_related_class(related, model)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/django/db/models/fields/related.py", line 388, in do_related_class
self.contribute_to_related_class(other, self.remote_field)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/parler/fields.py", line 58, in contribute_to_related_class
self.model.contribute_translations(cls)
File "/Users/itsd/Desktop/Web Projects/Django Projects/e-commerce_shop/env/myshop/lib/python3.7/site-packages/parler/models.py", line 944, in contribute_translations
raise TypeError("Translatable model {} does not appear to inherit from TranslatableModel".format(shared_model))
TypeError: Translatable model <class '__fake__.Product'> does not appear to inherit from TranslatableModel
I do not understand what the issue is preventing me from migrating the database.
Any help is appreciated.
My models.py file
from django.db import models
from django.urls import reverse
from parler.models import TranslatableModel, TranslatedFields
class Category(TranslatableModel):
translations = TranslatedFields(
name = models.CharField(max_length=200, db_index=True),
slug = models.SlugField(max_length=200, db_index=True,
unique=True)
)
class Meta:
# ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_list_by_category', args=[self.slug])
class Product(TranslatableModel):
translations = TranslatedFields(name = models.CharField(max_length=200,
db_index=True), slug = models.SlugField(max_length=200, db_index=True),
description = models.TextField(blank=True))
category = models.ForeignKey(Category, related_name='products',
on_delete=models.CASCADE)
image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_detail', args=[self.id, self.slug])
I do not understand what the issue may be. Here is my admin.py also. I believe the disconnect is between these two files after I make migrations and attempt to migrate.
from django.contrib import admin
from .models import Category, Product
from parler.admin import TranslatableAdmin
#admin.register(Category)
class CategoryAdmin(TranslatableAdmin):
list_display = ['name', 'slug']
def get_prepopulated_fields(self, request, obj=None):
return {'slug': ('name',)}
#admin.register(Product)
class ProductAdmin(TranslatableAdmin):
list_display = ['name', 'slug', 'price', 'available', 'created',
'updated']
list_filter = ['available', 'created', 'updated']
list_editable = ['price', 'available']
def get_prepopulated_fields(self, request, obj=None):
return {'slug': ('name',)}
I think the solution to this problem is in the same book you are working from.
Have you read this and made sure you changed the two occurences, not only one?
Edit the file migrations/0002_translations.py of the shop application and replace the two occurrences of the following line:
Copy
bases=(parler.models.TranslatedFieldsModelMixin, models.Model),
with the following one:
Copy
bases=(parler.models.TranslatableModel, models.Model),
This is a fix for a minor issue found in the django-parler version you are using. This change is necessary to prevent the migration from failing when applying it. This issue is related to creating translations for existing fields in the model and will probably be fixed in newer django-parler versions.
As far as I could see, the answer is that "parler" is currently broken. I ran into the same problem as you and even though I also tried to follow the documentation (and NOT the book!) at django-parler.readthedocs.io, the result was a COMPLETELY destroyed set of migrations, which I then had to painfully delete and rebuilt from scratch (always make complete backups BEFORE you do anything that touches migrations!).
I have opened a case with the Django Parler team #GitHub, but I have so far not received any answer. I believe this product is no longer maintained, or they have too many other things to work on.
In the end I ignored anything that used "Django-parler" in the book and jumped to the next section.
Once I will be working on my own product, I will most likely have to try other solutions from djangopackages.org
I know this is not the solution you were looking for, but I believe it is the correct answer, since "parler" simply seems to be broken at this point in time.
I am trying to programmatically creating a bunch of db objects and auto-save them to the db using the code below. But for some reason, I get the error below when I try to save the object (i.e. Tender object). The line the triggers the error is tender_obj.save() in the save_tender_to_db() function. What could be causing this problem?
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 316, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 353, in execute
output = self.handle(*args, **options)
File "C:\PROJECTS\leadshub\tender_matching_engine\management\commands\scrap_etenders.py", line 8, in handle
main()
File "C:\PROJECTS\leadshub\Tender_Loader\etenders_scraper.py", line 52, in main
save_tender_to_db(entry)
File "C:\PROJECTS\leadshub\Tender_Loader\etenders_scraper.py", line 129, in save_tender_to_db
description=container_tag[0]
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\query.py", line 413, in create
obj.save(force_insert=True, using=self.db)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 718, in save
force_update=force_update, update_fields=update_fields)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 748, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 831, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 869, in _do_insert
using=using, raw=raw)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\query.py", line 1136, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1288, in execute_sql
for sql, params in self.as_sql():
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1241, in as_sql
for obj in self.query.objs
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1241, in <listcomp>
for obj in self.query.objs
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1240, in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "C:\Users\ACER\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1168, in prepare_value
value = value.resolve_expression(self.query, allow_joins=False, for_save=True)
TypeError: 'NoneType' object is not callable
Please have a look at my code below.
#This is the model that stores the tender.
class Tender(models.Model):
tenderCategory = models.ManyToManyField(Category, blank=False) #this field holds the tender category, e.g. construction, engineering, human resources etc.
tenderProvince = models.ManyToManyField(Province, blank=False) #this is the province the tender was advertised from.
buyersName = models.CharField(max_length=100) #this is the name of the Buyer e.g. Dept. of Transport, Transnet, Dept of Agriculture etc.
summary = models.TextField(blank=False) #this is the tender title as per the Buyer.
refNum = models.CharField(max_length=100) #tender ref number as per the Buyer.
issueDate = models.DateTimeField(blank=True, null=True) #date the tender was published
closingDate = models.DateTimeField(default=timezone.now, blank=True, null=True) #tender closing date
siteInspectionDate = models.DateTimeField(blank=True, null=True)
siteInspection = RichTextField(blank=True, null=True) #site inspection date, if any
enquiries = RichTextField(blank=True, null=True) #this field stores details of the contact person, for the tender.
description = RichTextField(blank=True, null=True) #this is the body of the tender. the tender details are captured here.
assigned_keywords = models.ManyToManyField(Keywords, blank=True)
matched = models.BooleanField(default=False, blank=False)
capture_date = models.DateField(default=timezone.now, blank=False, null=False)
date_assigned = models.DateField(blank=True, null=True)
tDocLinks = RichTextField(blank=True)
def check_if_expired(self):
if self.closingDate < timezone.now():
return True
else:
return False
class Meta:
ordering = ['-closingDate']
def save_tender_to_db(data_rec_str):
try:
url_data_ls = data_rec_str.split(';')
sauce_2 = urllib.request.urlopen('http://www.etenders.gov.za{}'.format(url_data_ls[0]))
soup_2 = BeautifulSoup(sauce_2, 'html.parser')
# finds the container div in the html.
container_tag = soup_2.findAll('div', {'class': 'fieldset-wrapper'})
if len(container_tag) == 1:
tender_obj = Tender(
# tenderCategory=Category.objects.get(pk=1),
# tenderProvince=Province.objects.get(pk=1),
summary=url_data_ls[5].strip(),
refNum=url_data_ls[1].strip(),
issueDate=extract_date(url_data_ls[3].strip(), 2),
description=container_tag[0],
matched=False,
capture_date=timezone.now
)
tender_obj.save() #this is the line that triggers the error
else:
tender_obj = Tender(
# tenderCategory=Category.objects.get(pk=1),
# tenderProvince=Province.objects.get(pk=1),
summary=url_data_ls[5].strip(),
refNum=url_data_ls[1].strip(),
issueDate=extract_date(url_data_ls[2].strip(), 1),
closingDate=extract_date(url_data_ls[3], 2),
siteInspectionDate=extract_date(url_data_ls[4], 2),
description=container_tag[0],
tDocLinks = container_tag[1],
matched=False,
capture_date=timezone.now
)
tender_obj.save() #this is the line that triggers the error
except urllib.error.URLError as e:
print(e)
Lastly, when I uncomment the two lines below, I get the subsequent error. How can I solve this?
# tenderCategory=Category.objects.get(pk=1),
# tenderProvince=Province.objects.get(pk=1),
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use tenderCategory.set() instead.
I want to extend my 'User' model with the 'Profile' model. To facilitate this I've created the following model. I wanted to have the linked 'Profile' model be automatically created with each new 'User' model. Based on some comments on stackoverflow / research on the internet (simpleisbetterthancomplex) I came with the following solution:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
#Pushup related stats
total_pushups = models.IntegerField(default=0)
best_consecutive = models.IntegerField(default=0)
week_streak = models.IntegerField(default=0)
save = models.IntegerField(default=000)
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
However, every time I run this (whether through unit tests or 'create superuser' - I have no vies yet, I'm practicing TDD) I get the following error:
TypeError: 'int' object is not callable
Does anyone here know what I am doing wrong?
Edit: I've included a traceback of the error message that is shown after the 'create superuser' command
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
utility.execute()
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/core/management/__init__.py", line 356, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/core/management/base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 63, in execute
return super(Command, self).execute(*args, **options)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, **options)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 183, in handle
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/contrib/auth/models.py", line 170, in create_superuser
return self._create_user(username, email, password, **extra_fields)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/contrib/auth/models.py", line 153, in _create_user
user.save(using=self._db)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/contrib/auth/base_user.py", line 80, in save
super(AbstractBaseUser, self).save(*args, **kwargs)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/db/models/base.py", line 807, in save
force_update=force_update, update_fields=update_fields)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/db/models/base.py", line 847, in save_base
update_fields=update_fields, raw=raw, using=using,
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in send
for receiver in self._live_receivers(sender)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in <listcomp>
for receiver in self._live_receivers(sender)
File "/home/jasper/PycharmProjects/PushUpTuneUp/user_profiles/models.py", line 20, in create_user_profile
Profile.objects.create(user=instance)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/jasper/PycharmProjects/PushUpTuneUp/venv/lib/python3.5/site-packages/django/db/models/query.py", line 394, in create
obj.save(force_insert=True, using=self.db)
TypeError: 'int' object is not callable
You've defined a field called save, which is hiding the actual save method. Rename it to something else.
(And not related to your problem, but you certainly shouldn't have two receivers here. I can't see why you need the second one at all, but even if you did need that logic you should just put it in with the first one.)
Preface: I was writing my own Page app that used MPTT and a custom page model. This was working for me, but FlatPages is more refined than my custom Page Model and so I'm leaning toward just extending it.
from django.db import models
from django.contrib.flatpages.models import FlatPage
from mptt.models import MPTTModel
class ExtendedFlatPage(FlatPage, MPTTModel):
parent = models.ForeignKey('ExtendedFlatPage', null=True, blank=True, default=None, related_name="children", help_text="Hierarchical parent page (if any)")
class Meta:
ordering = ['flatpages__url']
order_with_respect_to = 'parent'
verbose_name = 'page'
verbose_name_plural = 'pages'
class MPTTMeta:
left_attr = 'mptt_left'
right_attr = 'mptt_right'
level_attr = 'mptt_level'
order_insertion_by = ['title']
def __unicode__(self):
return self.url
This almost works, except throws an error when I go to run python manage.py syncdb
Error:
iMac:cms colab$ python manage.py syncdb
Creating tables ...
Creating table my_flatpages_extendedflatpage
Traceback (most recent call last):
File "manage.py", line 14, in <module>
execute_manager(settings)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/__init__.py", line 438, in execute_manager
utility.execute()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/base.py", line 220, in execute
output = self.handle(*args, **options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/base.py", line 351, in handle
return self.handle_noargs(**options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/commands/syncdb.py", line 101, in handle_noargs
cursor.execute(statement)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/db/backends/util.py", line 34, in execute
return self.cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/db/backends/mysql/base.py", line 86, in execute
return self.cursor.execute(query, args)
File "build/bdist.macosx-10.6-intel/egg/MySQLdb/cursors.py", line 174, in execute
File "build/bdist.macosx-10.6-intel/egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
django.db.utils.DatabaseError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 2")
If anyone could point me in the right direction, I would greatly appreciate it. Thanks!
replace
class ExtendedFlatPage(FlatPage, MPTTModel):
with
class ExtendedFlatPage(MPTTModel, FlatPage):
This will allow MPTTModel class to override FlatPage attributes and methods.
#comment
It appears that something (an attribute, method) in FlatPage model overrides something in MPTTModel cousing this error.
order of classes you import from is important. here's an example:
class A:
attribute = 1
class B:
attribute = 2
class C(A,B):
pass
class C attribute value will be 1.