Django auto-deletes field related to MySQL Transactions

57 views
Skip to first unread message

RyanW

unread,
Oct 23, 2018, 1:43:20 AM10/23/18
to Django users
I have a Django site I'm developing, which I've connected to a MySQL db.  I haven't deployed into production yet, as I'm still working on a couple of things, however I leave the server running in development for initial data entry. 

I've noticed that some of the records already inputted gets deleted, seemingly randomly. I enabled logging on MySQL and found logs like the following:

6798 Connect
ryan45@cobb.eyes.uab.edu on downswebdb2
6798 Query
SET NAMES utf8
6798 Query
set autocommit=0
6798 Query
set autocommit=1
6798 Query
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
6798 Query
SELECT `Epe_epe`.`id`, `Epe_epe`.`epe_type`, `Epe_epe`.`epe_type2_id`, `Epe_epe`.`epe_date`, `Epe_epe`.`epe_ani`, `Epe_epe`.`epe_ani2_id`, `Epe_epe`.`epe_apn`, `Epe_epe`.`epe_apn2_id`, `Epe_epe`.`epe_weight`, `Epe_epe`.`epe_drug_type1`, `Epe_epe`.`epe_drug1`, `Epe_epe`.`epe_dose1`, `Epe_epe`.`epe_amount1`, `Epe_epe`.`epe_route1`, `Epe_epe`.`epe_time1`, `Epe_epe`.`epe_drug_type2`, `Epe_epe`.`epe_drug2`, `Epe_epe`.`epe_dose2`, `Epe_epe`.`epe_amount2`, `Epe_epe`.`epe_route2`, `Epe_epe`.`epe_time2`, `Epe_epe`.`epe_drug_type3`, `Epe_epe`.`epe_drug3`, `Epe_epe`.`epe_dose3`, `Epe_epe`.`epe_amount3`, `Epe_epe`.`epe_route3`, `Epe_epe`.`epe_time3`, `Epe_epe`.`epe_drug_type4`, `Epe_epe`.`epe_drug4`, `Epe_epe`.`epe_dose4`, `Epe_epe`.`epe_amount4`, `Epe_epe`.`epe_route4`, `Epe_epe`.`epe_time4`, `Epe_epe`.`epe_drug_type5`, `Epe_epe`.`epe_drug5`, `Epe_epe`.`epe_dose5`, `Epe_epe`.`epe_amount5`, `Epe_epe`.`epe_route5`, `Epe_epe`.`epe_time5`, `Epe_epe`.`epe_drug_type6`, `Epe_epe`.`epe_drug6`, `Epe_epe`.`epe_dose6`, `Epe_epe`.`epe_amount6`, `Epe_epe`.`epe_route6`, `Epe_epe`.`epe_time6`, `Epe_epe`.`epe_iso_start`, `Epe_epe`.`epe_iso_end`, `Epe_epe`.`epe_o2_end`, `Epe_epe`.`epe_start1`, `Epe_epe`.`epe_start2`, `Epe_epe`.`epe_start3`, `Epe_epe`.`epe_start4`, `Epe_epe`.`epe_start5`, `Epe_epe`.`epe_start6`, `Epe_epe`.`epe_start7`, `Epe_epe`.`epe_start8`, `Epe_epe`.`epe_hr1`, `Epe_epe`.`epe_hr2`, `Epe_epe`.`epe_hr3`, `Epe_epe`.`epe_hr4`, `Epe_epe`.`epe_hr5`, `Epe_epe`.`epe_hr6`, `Epe_epe`.`epe_hr7`, `Epe_epe`.`epe_hr8`, `Epe_epe`.`epe_spo2_1`, `Epe_epe`.`epe_spo2_2`, `Epe_epe`.`epe_spo2_3`, `Epe_epe`.`epe_spo2_4`, `Epe_epe`.`epe_spo2_5`, `Epe_epe`.`epe_spo2_6`, `Epe_epe`.`epe_spo2_7`, `Epe_epe`.`epe_spo2_8`, `Epe_epe`.`epe_temp1`, `Epe_epe`.`epe_temp2`, `Epe_epe`.`epe_temp3`, `Epe_epe`.`epe_temp4`, `Epe_epe`.`epe_temp5`, `Epe_epe`.`epe_temp6`, `Epe_epe`.`epe_temp7`, `Epe_epe`.`epe_temp8`, `Epe_epe`.`epe_etco2_1`, `Epe_epe`.`epe_etco2_2`, `Epe_epe`.`epe_etco2_3`, `Epe_epe`.`epe_etco2_4`, `Epe_epe`.`epe_etco2_5`, `Epe_epe`.`epe_etco2_6`, `Epe_epe`.`epe_etco2_7`, `Epe_epe`.`epe_etco2_8`, `Epe_epe`.`epe_rr1`, `Epe_epe`.`epe_rr2`, `Epe_epe`.`epe_rr3`, `Epe_epe`.`epe_rr4`, `Epe_epe`.`epe_rr5`, `Epe_epe`.`epe_rr6`, `Epe_epe`.`epe_rr7`, `Epe_epe`.`epe_rr8`, `Epe_epe`.`epe_comment` FROM `Epe_epe` WHERE `Epe_epe`.`id` = 1508
6798 Query
set autocommit=0
6798 Query
DELETE FROM `Epe_epe` WHERE `Epe_epe`.`id` IN (1508)
6798 Query
commit
6798 Query
set autocommit=1
6798 Quit
Where Epe_epe is from a model called Epe in my Django app. 

As far as I know, no user is performing delete commands on these records, so can I assume Django is performing these deletes in the background?  What would a trigger possibly be for these deletes?

Thank you

Matthew Pava

unread,
Oct 23, 2018, 2:16:24 PM10/23/18
to django...@googlegroups.com

Check your source code for any delete commands.

This might also be your authentication backend.  Which one are you using?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/91c6af18-cdf0-45f4-9f1c-e865c7128334%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

RyanW

unread,
Oct 23, 2018, 2:32:37 PM10/23/18
to Django users
I have a button to delete a record by the user, displayed inside a template as:

<td><a href={% url 'epedelete' epe.id %}><input class="btn btn-danger" type="button" value="Delete" /></a></td>

and the function in views.py

def delete(request, part_id=None):
    obj = epe.objects.get(id=part_id)
    obj.delete()
    return HttpResponseRedirect(reverse('epe_home'))

Other than that, I have some ForeignKey restraints on_delete to preserve integrity, like so:
    epe_ani2 = models.ForeignKey(
        Subjects,
        on_delete=models.PROTECT,
        null=True,
        blank=True
    )

As for the authentication backend, I'm using the default provided by Django:
['django.contrib.auth.backends.ModelBackend']

Thank you for the help!

To post to this group, send email to djang...@googlegroups.com.

Matthew Pava

unread,
Oct 23, 2018, 3:05:51 PM10/23/18
to django...@googlegroups.com

It doesn’t seem like Django would be doing this.

Do you have any other apps connected to the database?

You’ll probably want to surround your URL in quotation marks.  <a href=”{% url ‘epedelete’ epe.id %}”>

To post to this group, send email to django...@googlegroups.com.

RyanW

unread,
Oct 23, 2018, 4:04:11 PM10/23/18
to Django users
Yes, I honestly don't see how Django could be doing this either.  The only I could think of was user deletion, but no one has claimed to have done so.

No other apps are connected.

Thanks for the tip!!

Joel

unread,
Oct 23, 2018, 4:33:22 PM10/23/18
to django...@googlegroups.com
You could have a signal which captures all these and logs its origin.

To post to this group, send email to django...@googlegroups.com.

Matthew Pava

unread,
Oct 23, 2018, 4:54:17 PM10/23/18
to django...@googlegroups.com

And make sure your form is posting to the save view and not the delete view.  Maybe show us your template.

RyanW

unread,
Oct 24, 2018, 2:51:09 PM10/24/18
to Django users
Hi Matthew and Joel. Thanks for your help.

I'm attaching the models.py, views.py and templates for your reference.  I'm drawing a blank on the implementation that could trigger a delete.

Thanks again

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.

To post to this group, send email to djang...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

views.py
models.py
urls.py
epe_update.html
epe_new.html

Matthew Pava

unread,
Oct 24, 2018, 3:03:00 PM10/24/18
to django...@googlegroups.com

I can’t see anything wrong with what you’ve presented.  Try generating a new database and using that.  See if you still get random deletes on that database.

To post to this group, send email to django...@googlegroups.com.

RyanW

unread,
Oct 24, 2018, 3:10:33 PM10/24/18
to Django users
I've tried two separate MySQL db's on two separate servers.  They both have given me deletes.  What's strange is that I've set up a local copy on my laptop with both a local Postgres DB and MySQL connection, and I don't get the same deletes.

I've narrowed it down that it must be something the users are doing to trigger these deletes, based on logs that would've put them active during a time of a delete.

Matthew Pava

unread,
Oct 24, 2018, 3:22:46 PM10/24/18
to django...@googlegroups.com

In that case, is there something in a template that is possibly calling the delete view based on some user trigger, i.e. some Javascript function?

To post to this group, send email to django...@googlegroups.com.

C. Kirby

unread,
Oct 24, 2018, 6:24:12 PM10/24/18
to Django users
Is this happening to production users? It is probably because their browser is doing pre-fetch of links to speed up their UX. GET request are considered by the browser to be safe (non-destructive) and ideally idempotent. YOu should _never_ put a destructive action behind a GET, it should always be behind a POST or (even better if you are going the full REST route) DELETE.

RyanW

unread,
Oct 24, 2018, 11:22:08 PM10/24/18
to Django users
Yes, it is. Are you referring to 'delete' method in my views?

Mark Phillips

unread,
Oct 24, 2018, 11:36:12 PM10/24/18
to django users
Just a wild guess - do you have a cascade delete in your models that is causing the deletion? Is a user deleting another object, and that is triggering a cascade delete on a different model?

Mark

To post to this group, send email to django...@googlegroups.com.

RyanW

unread,
Oct 24, 2018, 11:39:11 PM10/24/18
to Django users
Hi Mark,

I did at one point, but I don't any longer ( I use RESTRICT now). 

Would you guys mind if I attached a copy of the app for review?

Thank you!

C. Kirby

unread,
Oct 25, 2018, 1:37:35 PM10/25/18
to Django users
The delete method in your views, yes, but also how you build the button. You should use a form with a hidden field (the id to delete), and the button ("Delete") should be the form submit. Then on the view side you should use a standard form handler (if request.POST....etc) to handle things. What is probably happening is the browser is automatically following the <a> tag to do prefetching, and causing the record to delete. Browsers will not prefetch "POST" verbs (so, a form post)

RyanW

unread,
Oct 27, 2018, 7:31:07 PM10/27/18
to Django users
Thanks for the info. Do you know of a way that I can confirm this is happening?

Best,
- Ryan
Reply all
Reply to author
Forward
0 new messages