My proposal to create a new exception

2020-02-08 Thread Victor Porton
In https://code.djangoproject.com/ticket/31239 I proposed to create 
QueryDictKeyError derived from MultiValueDictKeyError and raise this 
exception on a missing parameter in request.GET and request.POST.

It is to be done to handle error in user data easily:

try:
 x = request.GET['x']
except MultiValueDictError:
 return response("Missing user data 'x'", status=404)
try:
 y = request.GET['y']
except MultiValueDictError:
 return response("Missing user data 'y'", status=404)

is much more cumbersome and error-prone than:

def handle_exception(self, exc):
  if isinstance(exc, QueryDictKeyError):
# It is an unwise assumption that this is necessarily missing HTTP 
param,
# but rewriting it in other way would be time consuming (and maybe even 
more error prone).
return MyErrorResponse({"code": "PAR_1", "message": "Missing param.", 
"field": exc.args[0]})

The latter may be added to a base view to handle such errors in the entire 
project easily.
This handle_exception() could be even integrated into the core of Dajngo to 
handle such errors automatically without the user writing this code 
manually repeatedly.
Moreover, the above code is much more maintenable, as no need to change 
error messages in each and every view, if a user wants to change the error 
message.

Programming is about automation and we need the task about handling user 
input errors to be done automatically.

@felixxm claims "Creating a single method to catch and handle all kind of 
exceptions is error prone."
But the reverse things is true: not handling exception automatically leads 
to many code errors.

@felixxm's claim as valid as "use CGI instead of Django: using a CMS is 
error-prone, specify in the code exactly what you want rather to relying to 
a single method."
If code can be simplified, it needs to be simplified.

Please support my feature request.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/5f57ace7-6079-4f10-94ef-e7c9a67c7883%40googlegroups.com.


Re: My proposal to create a new exception

2020-02-09 Thread Victor Porton
Just because your code repeated in each and every form can be eliminated 
and we can check it all in one place,


shortening code, eliminating duplication, reducing possibilities of errors.

On 09/02/2020 12:45, Steven Mapes wrote:
Perhaps I'm totally missing the point and use case for this but is 
there any reason you are not simply using any of these


|
ifexpected_key isnotinrequest.GET:
returnMyErrorResponse(...)
|

|
ifnotrequest.GET.get("expected_key",None):
returnMyErrorResponse(...)
|


|
required =["one","two","three","four"]
ifnotall(k inrequest.GET.keys()fork inrequired):
returnMyErrorResponse(...)
|

I've used the latter approach if I have required parameters in a 
GET/POST and I'm not using forms. I  just adding the check to a base 
view and having required

be an attribute

On Sunday, 9 February 2020 05:15:01 UTC, Victor Porton wrote:

In https://code.djangoproject.com/ticket/31239
<https://code.djangoproject.com/ticket/31239> I proposed to create
QueryDictKeyError derived from MultiValueDictKeyError and raise
this exception on a missing parameter in request.GET and request.POST.

It is to be done to handle error in user data easily:

|
try:
 x =request.GET['x']
exceptMultiValueDictError:
returnresponse("Missing user data 'x'",status=404)
try:
| y =request.GET['y']
exceptMultiValueDictError:
returnresponse("Missing user data 'y'",status=404)
|
|

is much more cumbersome and error-prone than:

|
def handle_exception(self, exc):
  if isinstance(exc, QueryDictKeyError):
    # It is an unwise assumption that this is necessarily missing
HTTP param,
    # but rewriting it in other way would be time consuming (and
maybe even more error prone).
    return MyErrorResponse({"code": "PAR_1", "message": "Missing
param.", "field": exc.args[0]})
|

The latter may be added to a base view to handle such errors in
the entire project easily.
This handle_exception() could be even integrated into the core of
Dajngo to handle such errors automatically without the user
writing this code manually repeatedly.
Moreover, the above code is much more maintenable, as no need to
change error messages in each and every view, if a user wants to
change the error message.

Programming is about automation and we need the task about
handling user input errors to be done automatically.

@felixxm claims "Creating a single method to catch and handle all
kind of exceptions is error prone."
But the reverse things is true: not handling exception
automatically leads to many code errors.

@felixxm's claim as valid as "use CGI instead of Django: using a
CMS is error-prone, specify in the code exactly what you want
rather to relying to a single method."
If code can be simplified, it needs to be simplified.

Please support my feature request.
||
||

--
You received this message because you are subscribed to a topic in the 
Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit 
https://groups.google.com/d/topic/django-developers/SIl46zbIdIc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to 
django-developers+unsubscr...@googlegroups.com 
<mailto:django-developers+unsubscr...@googlegroups.com>.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/2423f3eb-e656-4084-a9c3-94e1ea41e969%40googlegroups.com 
<https://groups.google.com/d/msgid/django-developers/2423f3eb-e656-4084-a9c3-94e1ea41e969%40googlegroups.com?utm_medium=email&utm_source=footer>.


--
You received this message because you are subscribed to the Google Groups "Django 
developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/729ddf70-4bfe-e72e-1652-35b1d2e2cee4%40narod.ru.


Re: Composite fields

2016-10-16 Thread Victor Porton
I have implemented something like this: 
https://bitbucket.org/portonv/composite-fields

(I did my implementation before reading my thread.)

Please feel free to use and modify my code.

Well, now I should read this thread and 
https://github.com/django/deps/blob/master/draft/0191-composite-fields.rst

On Wednesday, March 4, 2015 at 3:16:37 PM UTC+2, Thomas Stephenson wrote:
>
> Considering the past two proposals I've made here, I doubt I'll get more 
> than an echo chamber effect on this one.
>
> For the past week or so I've spent a bit of time on a feature I've always 
> wanted to see land in django -- composite fields. The tickets have been 
> open in the bug tracker for quite some time (and there's a few related 
> ones, such as multi-column primary keys that can all be killed with the one 
> stone).
>
> The work is available on this branch of my fork of django 
>  for the moment 
> -- I haven't opened up a PR yet because there's still some features that 
> are still to be implemented that will be explained below, but I want to 
> give everybody a chance to tell me where I can stick it before I spend 
> *too* much time on it.
>
> So, without further ado, the proposal.
>
>
> Composite Fields - Implemented
>
> A composite field is an encapsulation of the functionality of a subset of 
> fields on a model. Composite fields can be defined in one of two ways:
>
> 1. Statically declared composite fields
>
> A statically declared composite field is defined in the same way a django 
> model is defined. There are two customisable transformation functions, 
> CompositeField.value_to_dict(self, value) and 
> CompositeField.value_from_dict(self, value) which can be used to associate 
> the field with a python object.
>
> All the serialization functions are implemented via the implementations of 
> the subfields.
>
> For example,  
>
> class MoneyField(models.CompositeField):
>currency_code = models.CharacterField(max_length=3)
>amount = models.DecimalField(max_digits=16, decimal_digits=4)
>
>## Overriding __init__ can be used to pass field parameters to the 
> subfields
>
>def value_from_dict(self, value):
>if value is None:
>   return None
>return Money(**value)
>
>def value_to_dict(self, value):
>   if value is None:
>  return None
>   return {attr: getattr(value, attr) for attr in ('currency_code', 
> 'amount')}
>
> 2. Inline composite fields.
>
> An inline composite field is declared at the field definition site on the 
> body of a model, by providing the subfields as the 'fields' argument of the 
> CompositeField constructor. There are no transformation parameters 
> available to override when declaring a composite field in this fashion -- 
> the value of the field is always available as a python `dict` as an 
> attribute on the MyModel
>
> class MyModel(models.Model):
> id = models.CompositeField(fields = [
>('a', models.IntegerField()),
>('b', models.CharField(max_length=30)
> ], primary_key=True)
>
> This method for defining composite fields has a few drawbacks, but can be 
> useful if the only reason to add the composite field to the model was to 
> implement a unique_together or index_together constraint *
>
> * Although it's still possible to do that directly on class Meta.
>
> 3. Null
>
> Setting the value of a multi-column field to NULL is different than 
> setting any of the individual subfields to NULL. But there are cases (e.g. 
> Money) where we would like to be able to set `null=True` on a composite 
> field, but still retain 'NOT NULL' constraints on each of the subfield 
> columns.
>
> To solve this problem, every table which implements a CompositeField will 
> also add an implicit (semi-hidden) `isnull` subfield on the attribute, 
> which keeps track of whether it is the value of the composite field that is 
> null, or any of the particular subfields.
>
> 3. Querying.
>
> The syntax for querying over the subfields of a composite field will be 
> familiar to anyone who has queried over a relationship attribute in django.
>
> model.objects.filter(price__currency_code='USD', 
> price__amount__lt=Decimal('50.00')).all()
>
> In addition, composite fields can be queried via EXACT and IN lookups. It 
> is possible to implement custom lookups for specific statically defined 
> fields, but not recommended and not part of the official API.
>
> 4. Restrictions
>
> The following restrictions are currently imposed on the use of composite 
> fields. None of these are restrictions that can't be worked around in 
> future extensions, but they're restrictions which considerably simplify 
> both the implementation and API.
>
> - No related fields as a subfield of a composite field
> - No nested composite fields
> - No inheritance of composite fields (apart from inheriting from 
> CompositeField itself).
>
> 5. Changes to the Field API
>
> As discussed in the other thread I 

Need to get user_id outside of a view

2017-01-29 Thread Victor Porton
See also
https://code.djangoproject.com/ticket/27786

I attempt to make file storage behavior dependent on the current user. 
(In fact, I attempted to store the ID of the uploader of a given file
into the database, so that other users could not list or delete this
file. Also I tried to store the file in a secret directory (directory
with a secret hash as its name) so that other users could not read it
without receiving an explicit link from the uploader.) I wrote code
like this:

class MyStorage(FileSystemStorage):
# ...

def get_user(self):
SessionStore =
import_module(settings.SESSION_ENGINE).SessionStore
s = SessionStore()
s.load()
# print({id: s[id] for id in s.keys()})  # FIXME
# user = apps.get_model('User').objects.get(id=s['user_id'])
return s['user_id']

This is set as

DEFAULT_FILE_STORAGE = 'xxx_storage_app.storage.MyStorage'

So I expect every form with a file to upload using MyStorage (and so
the upload algorithm depends on the current user).

But s behaves as an empty hash (without user_id element), as revealed
by the commented "FIXME" line.

We need either to make SessionStore to support this use case or
massively rewrite API to pass `request` to the form and ultimately to
the storage. I think we can do this without losing backward
compatibility using default function arguments.

It is a big API change, but it is necessary to support storage
dependent on the current user. It is a real and important use case for
our project.

Let us discuss the details, what is the best way to implement this in
future versions of Django.

Sorry for an offtopic, but can you advise me how to do it without
rewriting Django core?

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/1485713514.10180.3.camel%40narod.ru.
For more options, visit https://groups.google.com/d/optout.


Re: Need to get user_id outside of a view

2017-01-29 Thread Victor Porton
Probably a good way to solve this problem is to add `request` (with default 
`None`) argument to `Model.save` method, which could then be passed to the 
storage used for file fields.

Let us discuss if this is a good solution or can we invent something better.

On Sunday, January 29, 2017 at 8:12:10 PM UTC+2, Victor Porton wrote:
>
> See also 
> https://code.djangoproject.com/ticket/27786 
>
> I attempt to make file storage behavior dependent on the current user. 
> (In fact, I attempted to store the ID of the uploader of a given file 
> into the database, so that other users could not list or delete this 
> file. Also I tried to store the file in a secret directory (directory 
> with a secret hash as its name) so that other users could not read it 
> without receiving an explicit link from the uploader.) I wrote code 
> like this: 
>
> class MyStorage(FileSystemStorage): 
> # ... 
>
> def get_user(self): 
> SessionStore = 
> import_module(settings.SESSION_ENGINE).SessionStore 
> s = SessionStore() 
> s.load() 
> # print({id: s[id] for id in s.keys()})  # FIXME 
> # user = apps.get_model('User').objects.get(id=s['user_id']) 
> return s['user_id'] 
>
> This is set as 
>
> DEFAULT_FILE_STORAGE = 'xxx_storage_app.storage.MyStorage' 
>
> So I expect every form with a file to upload using MyStorage (and so 
> the upload algorithm depends on the current user). 
>
> But s behaves as an empty hash (without user_id element), as revealed 
> by the commented "FIXME" line. 
>
> We need either to make SessionStore to support this use case or 
> massively rewrite API to pass `request` to the form and ultimately to 
> the storage. I think we can do this without losing backward 
> compatibility using default function arguments. 
>
> It is a big API change, but it is necessary to support storage 
> dependent on the current user. It is a real and important use case for 
> our project. 
>
> Let us discuss the details, what is the best way to implement this in 
> future versions of Django. 
>
> Sorry for an offtopic, but can you advise me how to do it without 
> rewriting Django core? 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/6db56f76-6ac0-4e24-b42b-3c5b800a749d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Need to set socket options, for no breaking after a timeout

2017-05-12 Thread Victor Porton
About https://github.com/django/channels

In the past I dealt with another Python WebSocket engine (unrelated to 
Django). The connection was breaking after a timeout. I solved this problem 
adding:

sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)

sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 150)

sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 150)


in the connection handler.


I strongly suspect that this is also needed for proper working of Django 
Channels.


Where can I hook this code up? (Where can I get the underlying Unix socket?)


Also probably these three sock.setsockopt calls should be added into the 
default constructor for a WebSocket. What do you think? We can provide a 
boolean argument, which when set to the non-default value would eliminate 
these extra calls. When it set to default value, should call these 
three sock.setsockopt (it should be the default, because breaking WS after 
a timeout is usually bad).

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/df05a571-7ca1-4e0c-9bfe-6c7721a3285c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.