Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: 'str' object is not callable when deleting a model with foreign key relationship

Tags:

python

django

I'm getting 'str' object is not callable when I try to delete an object that has a related object attached to it. What would be causing this? I don't get this error if there's no related object saved.

I'm using Django Rest Framework

urls.py

urlpatterns = patterns('',
    url(r'^api/', include('rest_framework.urls', namespace='rest_framework')),
    url(r'^api/projects/$', views.ProjectList.as_view()),
    url(r'^api/projects/(?P<pk>[0-9]+)/$', views.ProjectDetail.as_view()),
    url(r'^api/projects/(?P<project_id>[0-9]+)/intervals/$', views.IntervalList.as_view()),
    url(r'^api/projects/(?P<project_id>[0-9]+)/intervals/(?P<pk>[0-9]+)/$', views.IntervalDetail.as_view()),

views.py

class ProjectDetail(APIView):
  permission_classes = (IsAuthenticated,)
  def get_object(self, pk, req):
    try:
      return Project.objects.get(pk=pk, user=req.user.id)
    except Project.DoesNotExist:
      raise Http404
  def get(self, request, pk, format=None):
    project = self.get_object(pk, request)
    serializer = ProjectSerializer(project)
    return Response(serializer.data)
  def put(self, request, pk, format=None):
    project = self.get_object(pk, request)
    serializer = ProjectSerializer(project, data=request.data)
    if serializer.is_valid():
      serializer.save(user=request.user)
      return Response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  def delete(self, request, pk, format=None):
    project = self.get_object(pk, request)
    project.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

serializers.py

class ProjectSerializer(serializers.ModelSerializer):
  intervals = IntervalSerializer(many=True, read_only=True)
  statements = StatementSerializer(many=True, read_only=True)
  class Meta:
    model = Project
    fields = (
      'id',
      'project_name',
      'project_description',
      'project_url',
      'project_logo',
      'deadline',
      'client_name',
      'client_email',
      'total_time',
      'hourly_rate',
      'fixed_rate',
      'balance',
      'payments',
      'completed',
      'paid',
      'created_at',
      'updated_at',
      'user',
      'intervals',
      'statements'
    )

models.py

class Interval(models.Model):
  def __str__(self):
    return self.project.project_name + ": " + self.description[:50] + " (" + str(self.id) + ")"
  project = models.ForeignKey(Project, related_name='intervals', on_delete='models.CASCADE', null=True, blank=True)
  start = models.DateTimeField(default=timezone.now, null=True, blank=True)
  end = models.DateTimeField(null=True, blank=True)
  total = models.DurationField(default=timedelta, blank=True)
  description = models.TextField(blank=True)
  created_at = models.DateTimeField(default=timezone.now)
  updated_at = models.DateTimeField(auto_now=True)

  class Meta:
    ordering = ('created_at',)

class Project(models.Model):
  def __str__(self):
    return self.project_name+" ("+str(self.id)+")"
  user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='projects', on_delete='models.CASCADE', null=True, blank=True)
  project_name = models.CharField(max_length=50)
  project_description = models.TextField(blank=True, null=True)
  project_url = models.URLField(max_length=200, blank=True, null=True)
  project_logo = models.ImageField(upload_to=logo_path, blank=True, null=True)
  deadline = models.DateTimeField(blank=True, null=True)
  client_name = models.CharField(max_length=50, blank=True, null=True)
  client_email = models.EmailField(blank=True, null=True)
  total_time = models.PositiveIntegerField(default=0)
  hourly_rate = models.DecimalField(max_digits=8, decimal_places=2, default=Decimal('0.00'), blank=True, null=True)
  fixed_rate = models.DecimalField(max_digits=8, decimal_places=2, default=Decimal('0.00'), blank=True, null=True)
  balance = models.DecimalField(max_digits=8, decimal_places=2, default=Decimal('0.00'))
  payments = models.DecimalField(max_digits=8, decimal_places=2, default=0, blank=True)
  completed = models.BooleanField(default=False)
  paid = models.BooleanField(default=False)
  created_at = models.DateTimeField(default=timezone.now)
  updated_at = models.DateTimeField(auto_now=True)

  class Meta:
    ordering = ('created_at',)

traceback

Traceback:
File "/vagrant/invenv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/vagrant/invenv/lib/python3.4/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)
File "/vagrant/invenv/lib/python3.4/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)
File "/vagrant/invenv/lib/python3.4/site-packages/rest_framework/views.py" in dispatch
  466.             response = self.handle_exception(exc)
File "/vagrant/invenv/lib/python3.4/site-packages/rest_framework/views.py" in dispatch
  463.             response = handler(request, *args, **kwargs)
File "/vagrant/invoices/views.py" in delete
  82.     project.delete()
File "/vagrant/invenv/lib/python3.4/site-packages/django/db/models/base.py" in delete
  895.         collector.collect([self])
File "/vagrant/invenv/lib/python3.4/site-packages/django/db/models/deletion.py" in collect
  229.                         field.rel.on_delete(self, field, sub_objs, self.using)
like image 647
aperture Avatar asked Dec 03 '22 16:12

aperture


1 Answers

You've set on_delete as a string, instead of a constant. It should be:

project = models.ForeignKey(Project, related_name='intervals', on_delete=models.CASCADE, null=True, blank=True)
like image 197
Daniel Roseman Avatar answered Dec 05 '22 05:12

Daniel Roseman