Tuesday, December 28, 2021

Re: Eliminating inter-request race conditions

Hi Nick,

maybe this is a case for optimistic locking?
Does the thread at https://groups.google.com/d/msg/django-users/R7wJBTlC8ZM/MIzvYkWyCwAJ help?

Best regards,
Carsten


Am 27.12.21 um 06:36 schrieb Nick Farrell:
> Hi all.
>
> I've been using Django for quite a number of years now, in various ways. Most of the time, I find myself needing to create custom solutions to solve what appears to be a very common problem. 
>
> During the Christmas downtime, I decided to scratch this itch, and am putting together what will hopefully turn into a solution to what I'll describe below. I'm writing this here to get a sense of what the Django community sees in this: is this a niche problem, is it shared by a few others, or is the lack of these features a fundamental overnight in the core Django product?
>
> *The problems *(from highest to lowest priority)*:*
> *
> *
> *1)* a form is rendered, the data is changed by a different task/request, then the form is submitted, overwriting the recent changes.
>
> Whenever models can be modified by multiple users (or even the same user in different windows/tabs of their browser), this can happen. Also, if there are any background processes which can modify the data (e.g. celery, or various data synchronisation services), it's possible.
> In some situations this is no big deal, as the users do not really care, or you know that the latest data would overwrite the previous data anyway. But in general, this is a major risk, particularly when dealing with any health or financial data. 
>
> *2)* Not being able to safely lock a model/queryset beyond the lifetime of the request.
>
> This is related to problem 1, and solving problem 2 may in some circumstances solve problem 1 - but not always. For example, depending on how the lock is implemented, a "rogue" task/request may bypass the locking mechanism and force a change to the underlying data. Also, if a lock is based on a session, a user may have multiple tabs open in the same browser, using the same session state (via shared cookies)
>
> Solving this problem will reduce the chance that when a person does post a form update, that there is any conflict, meaning fewer tears.
>
> *3)* Not knowing that data has changed on the server until you submit a form.
>
> Ideally there would be a means for someone viewing/editing a form to immediately be notified if data changes on the server, obsoleting the current form. This reduces the amount of wasted time is spent completing a form which is already known to be out of sync, and will need to be redone anyway (as long as problem 1 is solved; otherwise, there'll be data loss)
>
> *4)* Smarter form validation
>
> There are three types of missing validation: 
> - the first is that the default widgets do not support even very simple client-side validation. For example, a text field might need to match a regular expression. 
> - the second type is an ability to provide (in the model definition) arbitrary javascript which can be executed client-side to provide richer realtime validation during data entry.
> - the third type involves effectively providing provisional form data to the server, and having Django validate() the form content without actually saving the result. This would allow (for example) inter-field dependencies to be evaluated without any custom code, providing near-realtime feedback to the user that their form is invalid
>
>
> *The solutions*
> This is based on a day or so's experimentation, and I very much welcome any feedback, both in terms of the usefulness of solving these problems in general, as well as suggestion on better ways to solve the problems,  before I go too far down any rabbit holes.
>
> *Enhanced forms*
> - when rendering a form (using e.g. as_p()), alongside the normal INPUT DOM elements, include additional hidden fields which store a copy of each form field's initial value. 
> - when a form is submitted, compare these hidden values against the current value in the database. If any of these do not match, the clean() method can raise a ValidationError, allowing the user to know what has happened, and that they will need to reload the form and try again, with the new stored values.
>
> This solution is minimally invasive. As well as modifying as_p() and friends, a django template tag can also be exposed for those users who are rendering their forms in a different way.
> Note that there is no reliance on additional attributed in the models: the CAS-like checking performed is explicitly on the rendered form fields; it does not matter if other model fields' values have changed, as someone editing the form can neither see these field values, nor will their POSTing modify these other fields' values.
> (I have implemented the above already, for generic model forms using a single model)
>
> *Locking*
> - provide a mixin which can be used on selected models. When used, a view (usually some sort of form view) can attempt to lock() the model. If successful (because it's not currently locked to someone else), only they can perform writes to the model, until the lock expires. 
> - if the lock has expired, anyone (including the user who took out an expired lock) may overate on the model instance.
> - the lock can be configured to either use the standard database ORM, or redis. Redis will be more performant, but should not be a hard requirement
> - there will be pain points associated with using this without the websocket solution, detailed below: there will not be a clean way to maintain the lock, if the time between consecutive requests is greater than the timeout value
>
> *Websocket*
> - provide a model mixin to enable websocket monitoring
> - use Django Channels to expose a websocket consumer
> - provide a templatetag which will include appropriate javascript into a web page to initialise the client connection (if any forms are configured to be monitored)
> - when the client initialises, it detects the form fields (as per the 'Enhanced Forms' solution) and registers the model instance(s) with the server, via the websocket.
> - whenever a monitored instance changes in Django, a signal is raised, pushing notifications to any clients, along with the new values
> - the client can immediately compare the new instance values to the original values on the form (stored in the hidden fields) and can update the widgets directly if required (e.g. setting a CSS class to indicate the input is invalid, and updating the validation message shown alongside that.
>
>
> A final aspect of the solution is the javascript widgets, but I feel my post is already about 5 times too long.
>
> Any thoughts/comments are welcome.
>
> Thanks.
>
> --
> 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+unsubscribe@googlegroups.com <mailto:django-users+unsubscribe@googlegroups.com>.
> To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/e9d6ee80-19d2-4ca2-aa1b-10daf7217182n%40googlegroups.com <https://groups.google.com/d/msgid/django-users/e9d6ee80-19d2-4ca2-aa1b-10daf7217182n%40googlegroups.com?utm_medium=email&utm_source=footer>.

--
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+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/1a689b41-e86c-9127-e579-022c48e53c21%40cafu.de.

Sunday, December 26, 2021

Eliminating inter-request race conditions

Hi all.

I've been using Django for quite a number of years now, in various ways. Most of the time, I find myself needing to create custom solutions to solve what appears to be a very common problem. 

During the Christmas downtime, I decided to scratch this itch, and am putting together what will hopefully turn into a solution to what I'll describe below. I'm writing this here to get a sense of what the Django community sees in this: is this a niche problem, is it shared by a few others, or is the lack of these features a fundamental overnight in the core Django product?

The problems (from highest to lowest priority):

1) a form is rendered, the data is changed by a different task/request, then the form is submitted, overwriting the recent changes.

Whenever models can be modified by multiple users (or even the same user in different windows/tabs of their browser), this can happen. Also, if there are any background processes which can modify the data (e.g. celery, or various data synchronisation services), it's possible.
In some situations this is no big deal, as the users do not really care, or you know that the latest data would overwrite the previous data anyway. But in general, this is a major risk, particularly when dealing with any health or financial data. 

2) Not being able to safely lock a model/queryset beyond the lifetime of the request.

This is related to problem 1, and solving problem 2 may in some circumstances solve problem 1 - but not always. For example, depending on how the lock is implemented, a "rogue" task/request may bypass the locking mechanism and force a change to the underlying data. Also, if a lock is based on a session, a user may have multiple tabs open in the same browser, using the same session state (via shared cookies)

Solving this problem will reduce the chance that when a person does post a form update, that there is any conflict, meaning fewer tears.

3) Not knowing that data has changed on the server until you submit a form.

Ideally there would be a means for someone viewing/editing a form to immediately be notified if data changes on the server, obsoleting the current form. This reduces the amount of wasted time is spent completing a form which is already known to be out of sync, and will need to be redone anyway (as long as problem 1 is solved; otherwise, there'll be data loss)

4) Smarter form validation

There are three types of missing validation: 
- the first is that the default widgets do not support even very simple client-side validation. For example, a text field might need to match a regular expression. 
- the second type is an ability to provide (in the model definition) arbitrary javascript which can be executed client-side to provide richer realtime validation during data entry.
- the third type involves effectively providing provisional form data to the server, and having Django validate() the form content without actually saving the result. This would allow (for example) inter-field dependencies to be evaluated without any custom code, providing near-realtime feedback to the user that their form is invalid


The solutions
This is based on a day or so's experimentation, and I very much welcome any feedback, both in terms of the usefulness of solving these problems in general, as well as suggestion on better ways to solve the problems,  before I go too far down any rabbit holes.

Enhanced forms
- when rendering a form (using e.g. as_p()), alongside the normal INPUT DOM elements, include additional hidden fields which store a copy of each form field's initial value. 
- when a form is submitted, compare these hidden values against the current value in the database. If any of these do not match, the clean() method can raise a ValidationError, allowing the user to know what has happened, and that they will need to reload the form and try again, with the new stored values.

This solution is minimally invasive. As well as modifying as_p() and friends, a django template tag can also be exposed for those users who are rendering their forms in a different way.
Note that there is no reliance on additional attributed in the models: the CAS-like checking performed is explicitly on the rendered form fields; it does not matter if other model fields' values have changed, as someone editing the form can neither see these field values, nor will their POSTing modify these other fields' values.
(I have implemented the above already, for generic model forms using a single model)

Locking
- provide a mixin which can be used on selected models. When used, a view (usually some sort of form view) can attempt to lock() the model. If successful (because it's not currently locked to someone else), only they can perform writes to the model, until the lock expires. 
- if the lock has expired, anyone (including the user who took out an expired lock) may overate on the model instance.
- the lock can be configured to either use the standard database ORM, or redis. Redis will be more performant, but should not be a hard requirement
- there will be pain points associated with using this without the websocket solution, detailed below: there will not be a clean way to maintain the lock, if the time between consecutive requests is greater than the timeout value

Websocket
- provide a model mixin to enable websocket monitoring
- use Django Channels to expose a websocket consumer
- provide a templatetag which will include appropriate javascript into a web page to initialise the client connection (if any forms are configured to be monitored)
- when the client initialises, it detects the form fields (as per the 'Enhanced Forms' solution) and registers the model instance(s) with the server, via the websocket.
- whenever a monitored instance changes in Django, a signal is raised, pushing notifications to any clients, along with the new values
- the client can immediately compare the new instance values to the original values on the form (stored in the hidden fields) and can update the widgets directly if required (e.g. setting a CSS class to indicate the input is invalid, and updating the validation message shown alongside that.


A final aspect of the solution is the javascript widgets, but I feel my post is already about 5 times too long.

Any thoughts/comments are welcome.

Thanks.

--
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+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/e9d6ee80-19d2-4ca2-aa1b-10daf7217182n%40googlegroups.com.

Friday, December 24, 2021

Re: Why does sqlmigrate need a connection to an existing database?

To any future readers, the real answer is that connections are deeply baked into how Django migrations operate. Things as seemingly simple as `can_migrate_model` require a connection. The other problems pointed out by Jason are easily patched, but the schema_editor (and all of the migration operations in migrations/operations which rely on the schema_editor) totally break without a connection.

I think it could be done, but it isn't an easy patch.
On Saturday, 11 December 2021 at 07:59:32 UTC-8 Jason wrote:
https://github.com/django/django/blob/main/django/db/migrations/loader.py#L20-L40

the comment in the migration loader class probably explains your question.  also, look at `collect_sql` at the bottom, and how its used at the end of sqlmigrate. specifically, it uses schema editor (https://docs.djangoproject.com/en/3.2/ref/schema-editor/#module-django.db.backends.base.schema) as a context manager to have the connection turn migration nodes to SQL.





On Friday, December 10, 2021 at 12:06:21 PM UTC-5 shmuel....@partnerize.com wrote:
Build graph has a specific separate path for `if self.connection is None:`, so that shouldn't be an issue?
As far as atomicity, what if, in a case where no connection is found, it could just prompt: "No database connection found. Do you want your migration to be atomic? (y/N)"
On Thursday, 9 December 2021 at 05:01:31 UTC-8 Jason wrote:
It uses db connection in two places:

building the migration graph in order to load previous applied migrations and transaction begin/end wrapping

This makes sense, because you can have N unapplied migrations between the db and your migrations history package.  



On Tuesday, December 7, 2021 at 7:46:42 PM UTC-5 shmuel....@partnerize.com wrote:
Wondering why sqlmigrate needs a connection to an existing database.

I understand that for certain commands, it needs the database to generate the migration. But for most (basic) commands, no connection is really needed.

For example, I created a test project and generated migration files. Without ever running the `migrate` command, I was able to use `sqlmigrate` perfectly well on all migrations, save the last, which drops a `unique_together`.

I'm sure there are other commands which actually need a database connection (though I haven't found them yet). Seems to me sqlmigrate could be rewritten along the lines of:
  • Try to generate sql from migration file
  • If it hits a command it needs the database, attempt to connect
Or else:
  • If no connection, check if migration file needs connection to database
Is there something I'm unaware of?


This email may contain confidential material; unintended recipients must not disseminate, use, or act upon any information in it. If you received this email in error, please contact the sender and permanently delete the email.


This email may contain confidential material; unintended recipients must not disseminate, use, or act upon any information in it. If you received this email in error, please contact the sender and permanently delete the email.

--
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+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/7bdf8126-6f75-4569-88b5-12856bf565c5n%40googlegroups.com.

Thursday, December 23, 2021

Re: Django build file reg.

-----BEGIN PGP PUBLIC KEY BLOCK-----

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
BHO6KilQ+QLzSektD8IpHM7tR6P+5PP6AQ==
=NePe
-----END PGP PUBLIC KEY BLOCK-----On 23/12/2021 13.45, kavin kumar R wrote:
>
> *I did a project in django for a business motive and I want to sold it
> with out sorce code any one can help me to build a django a project wich
> can't be _reverse engineered_..*
>

You can't, so drop that idea. Let your lawyers deal with that instead of
trying to implement a non-working technical solution.

Kind regards,

Kasper Laudrup

--
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+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/0cb97d51-55f9-1018-f21e-791c4e622c06%40stacktrace.dk.

Re: get country from IP_addres.

In line with prior examples by others, take a look at this complete example leveraging GeoIP2

Get Visitor Location using GeoIP2 in Django
https://medium.com/@arrosid/get-visitor-location-using-geoip2-in-django-32ad3d417115

Geolocation with GeoIP2
https://docs.djangoproject.com/en/4.0/ref/contrib/gis/geoip2/

django-ip-geolocation 1.6.1
https://pypi.org/project/django-ip-geolocation/

On Thursday, December 23, 2021 at 7:25:06 AM UTC-7 whatsap...@gmail.com wrote:

في الخميس، ١٦ ديسمبر ٢٠٢١ ٤:٠٩ ص Amor Zamora <amorz...@gmail.com> كتب:
Can you help me?
I need to obtain the country of where the users access from the IP and insert that information into the sqlite3 database.

Little description.
I have an application that I have to do the statistics and insert into the sqlite3 database, the IP information, the country from which it is accessed, who generates the information and how many times has clicked on the application.
Question 1 is that I cannot find any suitable module in DJango that allows me to combine the information described above.
I am using. IP_address, os, daemonize and socket and I don't quite realize how to get the country from where it is accessed.
Thanks

--
Amor Zamora
Behind the distance, 
your mouth and mine hide, 
complices of a kiss, caresses, fantasies, 
distance as close as the sky and the sea, 
my piece is in your bed, in mine, is your love.
Behind the distance hide love, memories, 
encounters, experiences, circumstances, pain and good times, 
it is after her, the distant ones, 
that we leave feelings, 
but if we really miss, 
distance,
it is only your time.

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAKMTbHXbM4QFh5kRiShsroObKjefGzvRchX5m3S2ps6M95bwgQ%40mail.gmail.com.

--
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+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/e56de8d2-ede0-4b31-8063-8b44ceccba24n%40googlegroups.com.

Tuesday, December 21, 2021

Running tests fails in the test runner call_command

I've got a 3.2.10 installation and haven't run my unit tests in a long time. When I try now, I get a failure which seems to trace back to the test runner itself:

TypeError: Unknown option(s) for check command: databases. Valid options are: all, debug, force_color, help, names, no_color, pythonpath, quiet, settings, skip_checks, stderr, stdout, traceback, verbose, verbosity, version.

where the only mention of call_command with an explicit "databases" argument is in django/test/runner.py

I see this argument was introduced in 3.1 and was not present in 3.0.x and earlier.

Any hints on where to look for the root cause or how to patch it up?

TIA

- Tom

Monday, December 20, 2021

Re: How the social platforms deals each users data

-----BEGIN PGP PUBLIC KEY BLOCK-----

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
BHO6KilQ+QLzSektD8IpHM7tR6P+5PP6AQ==
=NePe
-----END PGP PUBLIC KEY BLOCK-----On 20/12/2021 08.08, Koushik Romel wrote:
> Like Twitter, Instagram and Facebook how to store users data separately
> it will also be helpful if you redirect me to any blog or any
> documentation to know completely about this
>

https://dev.to/earthcomfy/django-user-profile-3hik

Kind regards,

Kasper Laudrup

--
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+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/169baa3e-c140-2bf2-376e-875d1e94c99a%40stacktrace.dk.