AttributeError Exception raised when trying to bulk delete items in Django - python

I'm trying to bulk delete all of the comments on a dev instance of my Django website and Django is raising an AttributeException.
I've got the following code on a python prompt:
>>> from django.contrib.comments.models import Comment
>>> Comment.objects.all().delete()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/jeff/.virtualenvs/osl_main-website/lib/python2.6/site-packages/django/db/models/query.py", line 441, in delete
obj._collect_sub_objects(seen_objs)
File "/home/jeff/.virtualenvs/osl_main-website/lib/python2.6/site-packages/django/db/models/base.py", line 569, in _collect_sub_objects
sub_obj._collect_sub_objects(seen_objs, self, related.field.null)
File "/home/jeff/.virtualenvs/osl_main-website/lib/python2.6/site-packages/django/db/models/base.py", line 585, in _collect_sub_objects
delete_qs = rel_descriptor.delete_manager(self).all()
AttributeError: 'ReverseSingleRelatedObjectDescriptor' object has no attribute 'delete_manager'
I'm not sure as to why the delete statement is not working. Can anyone help me with why this isn't working and what I can do to fix it?
Additional details about my models:
I have another model called OslComment that inherits from Comment. I also have a Vote model that points to entries in OslComment.
BaseCommentAbstractModel
class BaseCommentAbstractModel(models.Model):
"""
An abstract base class that any custom comment models probably should
subclass.
"""
# Content-object field
content_type = models.ForeignKey(ContentType,
verbose_name=_('content type'),
related_name="content_type_set_for_%(class)s")
object_pk = models.TextField(_('object ID'))
content_object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_pk")
# Metadata about the comment
site = models.ForeignKey(Site)
Comment
class Comment(BaseCommentAbstractModel):
"""
A user comment about some object.
"""
# Who posted this comment? If ``user`` is set then it was an authenticated
# user; otherwise at least user_name should have been set and the comment
# was posted by a non-authenticated user.
user = models.ForeignKey(User, verbose_name=_('user'),
blank=True, null=True, related_name="%(class)s_comments")
user_name = models.CharField(_("user's name"), max_length=50, blank=True)
user_email = models.EmailField(_("user's email address"), blank=True)
user_url = models.URLField(_("user's URL"), blank=True)
comment = models.TextField(_('comment'), max_length=COMMENT_MAX_LENGTH)
# Metadata about the comment
submit_date = models.DateTimeField(_('date/time submitted'), default=None)
ip_address = models.IPAddressField(_('IP address'), blank=True, null=True)
is_public = models.BooleanField(_('is public'), default=True,
help_text=_('Uncheck this box to make the comment effectively ' \
'disappear from the site.'))
is_removed = models.BooleanField(_('is removed'), default=False,
help_text=_('Check this box if the comment is inappropriate. ' \
'A "This comment has been removed" message will ' \
'be displayed instead.'))
OslComment
class OslComment(Comment):
parent_comment = models.ForeignKey(Comment, blank=True, null=True, related_name='parent_comment')
inline_to_object = models.BooleanField(default=False)
edit_timestamp = models.DateTimeField()
transformed_comment = models.TextField(editable=False)
is_deleted_by_user = models.BooleanField(default=False)
Vote
class Vote(models.Model):
"""
A vote on an object by a User.
"""
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
object = generic.GenericForeignKey('content_type', 'object_id')
vote = models.SmallIntegerField(choices=SCORES)
Misc information:
Python Version: 2.6.5
Operating System: Linux Mint 9 (Linux 2.6.32-21-generic)
Django: 1.2
Database driver: postgresql_psycopg2 (2.2.1)

Edited: Originally I thought you couldn't do delete() on a QuerySet and was going to recommend you iterate over the items, but apparently you can do bulk deletes like that. Trying to iterate over the QuerySet might give you a better clue as to what's wrong, though.

Related

Exception Value: NOT NULL constraint failed: send_appdata.product_id_id

I am using a custom user model and when i am trying to reference it in other model i am getting an error.
Exception Value:
NOT NULL constraint failed: send_appdata.product_id_id
views.py
from django.contrib.auth import get_user_model
AppOnboarding = get_user_model()
# get data from json
#api_view(['POST'])
def index(request):
product_id = AppOnboarding.objects.get(pk=request.data['product_id'])
product_name = request.data['product_name']
product_url = request.data['product_url']
subject = request.data['subject']
body = request.data['body']
recipient_list = request.data['recipient_list']
sender_mail = request.data['sender_mail']
email_type = request.data['email_type']
broadcast_mail = request.data['broadcast_mail']
email_status = status.HTTP_200_OK
location = request.data['location']
# make an object of AppData
app_data = AppData(product_id=product_id, product_name=product_name, product_url=product_url,
subject=subject, body=body, recipient_list=recipient_list, sender_mail=sender_mail, email_type=email_type, broadcast_mail=broadcast_mail, email_status=email_status, location=location)
# save it to DB
app_data.save()
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.contrib.auth import get_user_model
AppOnboarding = get_user_model()
class AppData(models.Model):
# app_data_id = models.IntegerField(primary_key=True)
product_id = models.ForeignKey(AppOnboarding, on_delete=models.PROTECT)
product_name = models.CharField(max_length=100)
product_url = models.URLField()
subject = models.CharField(max_length=100)
body = models.TextField()
recipient_list = models.TextField()
sender_mail = models.EmailField(max_length=254)
email_type = models.CharField(max_length=50)
broadcast_mail = models.BooleanField()
email_status = models.CharField(max_length=50)
date_time = models.DateTimeField(auto_now_add=True)
location = models.CharField(max_length=100)
AppOnboarding is a custom user model in a different app.
I explored the similar questions but could not resolve the issue.
Any help is highly appreciated.
Have added this foreign key product_id recently (after the rest of model fields)?
If yes, you need to make it nullable (null=True) and run makemigrations then migrate
Found the error, when I manually checked using python shell, Apponboarding.objects.get(id=1) was returning Does not exits but Apponboarding.objects.get(id=2) and others it was returning email address instead of id. It is still not clear how the id started from 2 instead of 1 (since it is auto field) and why email is getting returned instead of id.

Django-Rest: Serialising ListField() - '_TaggableManager' object is not iterable

My goal is to add tags to a post. I'm using latest taggit (Requirement: Django-Taggit https://github.com/alex/django-taggit ) and DRF.
Goal: To pop tags only from posted request. For each tag in the post request to call post.tags.add("tag1","tag2") to add these tags to the model.
Currently, my post serialiser is:
class PostSerializer(serializers.ModelSerializer):
tags = serializers.ListField(
child=serializers.CharField(min_length=0, max_length=30)
)
...
def create(self, validated_data):
pub.set_trace()
tags_data = validated_data.pop('tags') # Need to pop tags only
# to_be_tagged, validated_data = self._pop_tags(validated_data)
images_data = self.context.get('view').request.FILES
post = Post.objects.create(**validated_data)
post.tags.add(*tags_data)
for image_data in images_data.values():
PostImage.objects.create(post=post, image=image_data)
return post
When I send a post request with the following data:
data = { 'title': 'First Post',
...
'tags':'["tag1"]'}
I get an error:
Exception Value: '_TaggableManager' object is not iterable
I also tried sending 'tags':'one, two, three' and simply one
Edit - PDB output:
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
> /Users/gr/Desktop/PycharmProjects/godo/api/serializers.py(112)create()
-> tags_data = validated_data.pop('tags')
(Pdb) tags_data
*** NameError: name 'tags_data' is not defined
(Pdb)
Models.py
from taggit.managers import TaggableManager
class Post(models.Model):
objects = LocationManager() # to sort by distance
tags = TaggableManager()
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=False)
description = models.TextField(max_length=500, blank=False)
def __str__(self):
return '{}'.format(self.title)
Are you sure about the content of tags_data variable? Could you put there traceback and debug it (see: using (i)pdb for debugging)?
I think wrong is these line:
post.tags.add(tags_data)
lets try:
post.tags.add(*tags_data)
The star unpack list. See these answer for reference: https://stackoverflow.com/a/4959580/953553
In my project I ma handling tags which are in model M2M and in serializer I decided to use this approach:
tags = serializers.SlugRelatedField(
many=True,
queryset=Tag.objects.all(),
slug_field='text'
)
my models:
class Spot(models.Model):
tags = models.ManyToManyField(Tag, related_name='spot_facilities', null=True, blank=True)
class Tag(models.Model):
text = models.CharField(max_length=100, unique=True)

Django - Select related or join on two different base models

I have two base models SiteData and Showoroom Service that have model structure as per the below.
I need the SiteData info but I also would like to get link_type from the showroomservice model if there is a matching ID.
ive tried a few things thus far, none are getting what I need, what is the best way to achieve this?
Thanks
select related
>>> nd = ShowroomService.objects.select_related('site').all()
>>> nd
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 229, in __repr__
return '<%s %r>' % (self.__class__.__name__, data)
File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py", line 590, in __repr__
u = six.text_type(self)
TypeError: __str__ returned non-string (type SiteData)
Combining :
>>> complete_data = site_data | monitoring_data
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 310, in __or__
combined.query.combine(other.query, sql.OR)
File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/query.py", line 529, in combine
"Cannot combine queries on two different base models."
AssertionError: Cannot combine queries on two different base models.
chaining
>>> final_data = chain(monitoring_data, site_data)
>>> for i in final_data:
... '{} {}'.format(i.location,i.link_Type)
...
Traceback (most recent call last):
File "<console>", line 2, in <module>
AttributeError: 'ShowroomService' object has no attribute 'location'
sites.models.py
class SiteData(models.Model):
location = models.CharField(max_length=50)
site_type = models.ForeignKey(SiteTypes, verbose_name="Site Type", \
on_delete=models.PROTECT)
subnet = models.GenericIPAddressField(protocol='IPv4')
routed_subnet = models.GenericIPAddressField(protocol='IPv4', \
verbose_name="Routed Link Subnet", blank=True, null=True)
bgp_as = models.CharField(max_length=6, verbose_name="BGP AS Number")
opening_date = models.DateField(verbose_name="Showroom opening date")
last_hw_refresh_date = models.DateField(verbose_name="Date of latest hardware refresh", \
blank=True, null=True)
is_live = models.BooleanField(default=False, verbose_name="Is this a live site?")
tel = models.CharField(max_length=20, blank=True, null=True)
address = models.CharField(max_length=255, blank=True, null=True)
town = models.CharField(max_length=255, blank=True, null=True)
...
class Meta:
verbose_name = "Site Data"
verbose_name_plural = "Site Data"
ordering = ('location',)
permissions = (
("can_view", "Can View"),
("can_view_mgmt", "Can View Management"),
)
def __str__(self):
return self.location
monitoring.models.py
from sites.models import SiteData
class ShowroomService(models.Model):
site = models.ForeignKey(SiteData, verbose_name="Site", \
on_delete=models.PROTECT)
link_type = models.CharField(max_length=200, blank=True, null=True)
preference = models.CharField(max_length=200, blank=True, null=True)
timestamp = models.DateTimeField(auto_now_add=True, blank=True, null=True)
dashboard = models.BooleanField(default=True, verbose_name="display on monitoring dashboard?")
class Meta:
verbose_name = "Showroom Service Data"
verbose_name_plural = "Showroom Service Data"
def __str__(self):
return self.site
You can pull all related objects using django's "related manager". Documentation is available here: https://docs.djangoproject.com/en/2.0/ref/models/relations/#related-objects-reference
By calling showroom_service_set on a SiteData model, you can get the set of child records for each SiteData.
Just to explain why the listed attempts failed as well:
your __str__ methods on your models need to return strings. If they don't, you'll get that exception.
The pipe operator | is used for ORing together queries in django. That chunk of code is attempting to combine a query for 2 different types of models.
With the chain attempt, you've created a list containing two different types of models. One of which doesn't have a location attribute.
Here's a chunk of code to get the link type for all ShowroomService models attached to a SiteData model:
for site_data in SiteData.objects.all():
for showroom in site_data.showroom_service_set.all():
print showroom.link_type
I'm not sure how django handles camel-casing with related objects, so showroom_service_set is my best guess. You might have to do a little leg work on this to figure out what the actual set is called.
EDIT: There's something called prefetch_related. Here's a SO answer about it; I think it'll get you what you're looking for: https://stackoverflow.com/a/13096423/769971

Django 1.7 modelform_factory form is always invalid with factory_boy created model

I'm using Django 1.7 and factory_boy to create some models. Here's the code:
In models.py:
class Address(models.Model):
first_line = models.CharField(max_length=50, blank=True)
second_line = models.CharField(max_length=50, blank=True)
city = models.CharField(max_length=30, blank=True)
state = models.CharField(max_length=2, blank=True)
zipcode = models.CharField(max_length=5, blank=True)
zipcode_ext = models.CharField(max_length=4, blank=True)
The associated factory in factories.py (same directory):
class AddressFactory(factory.django.DjangoModelFactory):
class Meta:
model = Address
first_line = "555 Main St."
second_line = "Unit 2"
city = "Chicago"
state = "IL"
zipcode = "60606"
zipcode_ext = "1234"
Now, given this code in the django shell:
>>> from models import Address
>>> from django.forms.models import modelform_factory
>>> AddressForm = modelform_factory(Address)
>>> from factories import AddressFactory
>>> a = AddressFactory.create()
>>> af = AddressForm(instance = a)
>>> af.is_valid()
False
For some reason, the call to is_valid seems to always return false, and I can't figure out why. There don't seem to any errors on the form, and clean(), clean_fields(), and validate_unique() all do not seem to raise errors on the instance.
Why does is_valid always return false?
This has nothing to do with factory_boy. Forms are always invalid if they don't have any data, which yours doesn't. The instance parameter is used to populate the form's initial data for display, and to determine the object ID for updating, but it isn't used to set that data on POST.
I'm not quite sure what you want to do with the form there, but you'd need to convert it to a POST dictionary and pass it to the form's data parameter for it to be valid.

Design problem with a component that should automatically create a database record when another one is saved

I have a situation where I want to create a menu item in the database whenever a record is created.
I need to design a component that will create the mentioned menu item.
I am using django-sitetree as the basic app for the menu.
It has the following model:
class TreeItem(models.Model):
PERM_TYPE_ANY = 1
PERM_TYPE_ALL = 2
PERM_TYPE_CHOICES = (
(PERM_TYPE_ANY, _('Any')),
(PERM_TYPE_ALL, _('All'))
)
title = models.CharField(_('Title'), max_length=100, help_text=_('Site tree item title. Can contain template variables E.g.: {{ mytitle }}.'))
hint = models.CharField(_('Hint'), max_length=200, help_text=_('Some additional information about this item that is used as a hint.'), blank=True, default='')
url = models.CharField(_('URL'), max_length=200, help_text=_('Exact URL or URL pattern (see "Additional settings") for this item.'), db_index=True)
urlaspattern = models.BooleanField(_('URL as Pattern'), help_text=_('Whether the given URL should be treated as a pattern.<br /><b>Note:</b> Refer to Django "URL dispatcher" documentation (e.g. "Naming URL patterns" part).'), db_index=True, default=False)
tree = models.ForeignKey(Tree, verbose_name=_('Site Tree'), help_text=_('Site tree this item belongs to.'), db_index=True)
hidden = models.BooleanField(_('Hidden'), help_text=_('Whether to show this item in navigation.'), db_index=True, default=False)
alias = CharFieldNullable(_('Alias'), max_length=80, help_text=_('Short name to address site tree item from a template.<br /><b>Reserved aliases:</b> "trunk", "this-children", "this-siblings" and "this-ancestor-children".'), db_index=True, blank=True, null=True)
description = models.TextField(_('Description'), help_text=_('Additional comments on this item.'), blank=True, default='')
inmenu = models.BooleanField(_('Show in menu'), help_text=_('Whether to show this item in a menu.'), db_index=True, default=True)
inbreadcrumbs = models.BooleanField(_('Show in breadcrumb path'), help_text=_('Whether to show this item in a breadcrumb path.'), db_index=True, default=True)
insitetree = models.BooleanField(_('Show in site tree'), help_text=_('Whether to show this item in a site tree.'), db_index=True, default=True)
access_loggedin = models.BooleanField(_('Logged in only'), help_text=_('Check it to grant access to this item to authenticated users only.'), db_index=True, default=False)
access_restricted = models.BooleanField(_('Restrict access to permissions'), help_text=_('Check it to restrict user access to this item, using Django permissions system.'), db_index=True, default=False)
access_permissions = models.ManyToManyField(Permission, verbose_name=_('Permissions granting access'), blank=True)
access_perm_type = models.IntegerField(_('Permissions interpretation'), help_text='<b>Any</b> — user should have any of chosen permissions. <b>All</b> — user should have all chosen permissions.', choices=PERM_TYPE_CHOICES, default=PERM_TYPE_ANY)
# These two are for 'adjacency list' model.
# This is the current approach of tree representation for sitetree.
parent = models.ForeignKey('self', verbose_name=_('Parent'), help_text=_('Parent site tree item.'), db_index=True, null=True, blank=True)
sort_order = models.IntegerField(_('Sort order'), help_text=_('Item position among other site tree items under the same parent.'), db_index=True, default=0)
# More code here...
Is it reasonable to configure inmenu, inbreadcrumbs etc. in the model's Meta class?
Is there a better way to do this?
Is it reasonable to check if a there is field name called title and use it for the menu item's title first and then search for a function called get_menu_item_title in the model?
Or should I pass the field/callable to the component's constructor? Or maybe this should be defined in the meta class as well?
You can use Signals.
from django.db.models.signals import post_save
from django.dispatch import receiver
from myapp.models import Record, TreeItem
#receiver(post_save, sender=Record)
def my_handler(sender, instance, created, raw):
if created:
item = TreeItem() # ..
Whenever new record is created you can create another item.

Categories