I'm glad it helped.

As you can see, the dispatch method I wrote does override the default
definition, but I return the super() dispatch method, so on the default
flow the end result is the same (the validity of the request would be
checked anyway, only after you set your class atribute).
To avoid this work that would be invalid if there is an error on the
request you could write a dispatch method that first gets the result of the
super (). dispatch, check if it was ok then do the work you need and return
the result of the dispatch after that.

And you could as well use the __init__ method for the class, but I'm not
sure the .as_view() function works as a constructor like that, I would need
to confirm the documentation, but there were some implementations that I
worked with that customized the __init__ of the view class so it would
probably work. A more philosophical question is if it is the proper
location for that work to be done, as the __init__ method could be called
even if the request is invalid, making your code try to do something weird.

Anyway, good luck on your project!

On Wed, Jun 6, 2018, 14:51 Mikkel Kromann <[email protected]> wrote:

> Thanks Daniel.
>
> Both your proposed solutions worked very well.
> For now, I don't have other information stuffed into my model definitions,
> so the urls.py approach could do.
> However, if I decide to put more information into models.py, the def
> dispatch() approach could be useful.
>
> One question though:
> Do I understand correctly, that your version of def dispatch() overwrites
> the Django dispatch method from UpdateView.
> As far as I can see, it checks the validity of the request method.
> Could I use def __init__ instead of def dispatch
>
>
> thanks + cheers, Mikkel
>
>
> From
> https://ccbv.co.uk/projects/Django/2.0/django.views.generic.edit/UpdateView/
> def dispatch(self, request, *args, **kwargs):
>     # Try to dispatch to the right method; if a method doesn't exist,
>     # defer to the error handler. Also defer to the error handler if the
>     # request method isn't on the approved list.
>     if request.method.lower() in self.http_method_names:
>         handler = getattr(self, request.method.lower(), self.
> http_method_not_allowed)
>     else:
>         handler = self.http_method_not_allowed
>     return handler(request, *args, **kwargs)
>
>
>
>
> onsdag den 6. juni 2018 kl. 16.12.06 UTC+2 skrev Daniel Germano Travieso:
>
>> Ok! I think I see your problem.
>>
>> It is a deeper understanding of python classes that may be the problem.
>> You see, "model" and "self" are class atributes of the python class that
>> houses your class based view (as every class in django is first a python
>> class).
>>
>> So, if you try to access the attribute "model" of the class, or the
>> attribute "self", a attribute that houses the instance of the class, on
>> it's class attributes definitions you will have problems, as the python
>> interpreter only load these modules lazyly, not actually going through on
>> finding the value for the attribute you referenced.
>>
>> One solution is to have that value (for the attribute "field" as a
>> @property that is a function that then the python interpreter will go
>> through and execute the reference lookup.
>>
>> Another solution is to set that value to be initially None, and set the
>> value for the fields on the dispatch method of the view, something like
>> class ItemUpdateView(UpdateView):
>>   template_name="foo.html"
>>   fields = None
>>
>>   def dispatch (self, request, *args, **kwargs):
>>     self.fields = self.model.fields
>>     return super(ItemUpdateView, self).dispatch(request, *args, **kwargs)
>>
>>
>>
>> But as of my understanding of your problem, you are trying to just
>> customize which form fields to display to the user based on which model the
>> user is updating, so you could just specify the form_class attribute on the
>> path (just as you did with the model).
>>
>> Hope it helps!
>>
>>
>> On Wed, Jun 6, 2018, 10:36 Mikkel Kromann <[email protected]>
>> wrote:
>>
> Hello Daniel.
>>>
>>> Thank you for your reply. Perhaps I was not explicit enough in
>>> describing my problem - it is far simpler than your solution indicates.
>>> In my model definitions, I already have a list of the fields to be
>>> represented in the form of UpdateView - it is an attribute in the form of a
>>> simple array called "fields".
>>> I don't want UpdateView to make a form for all columns of the model's
>>> data table, just the fields from my custom array in the Model objects.
>>>
>>> My problem is simply: How to access my custom attribute "field" in the
>>> Model attribute passed to the Class Based View function.
>>> As described, I get compilation errors, complaining that "model" and
>>> "self" are names not defined.
>>> From the documentation (and my so far not too great Python
>>> understandign) it is not clear to me whether "Model" is simply the name of
>>> the model, or if it is the entire Model object instance.
>>>
>>>
>>> thanks again, Mikkel
>>>
>>>
>>> onsdag den 6. juni 2018 kl. 15.01.05 UTC+2 skrev Daniel Germano Travieso:
>>>>
>>>> Hello!
>>>>
>>>> As you see on the documentation (
>>>> https://docs.djangoproject.com/en/2.0/topics/class-based-views/) for
>>>> the class based views, any arguments you pass to the class based view
>>>> .as_view() method will override attributes of the class based view, so if
>>>> you set MyCView.as_view(model=Foo) is the same as setting class MyCView:
>>>> model=Foo directly.
>>>>
>>>> Now to access the field names of the Model, you used to be able to call
>>>> a .get_field_names() or something like that but that is depreciated since
>>>> 1.10. Now to do that you should use the Model._meta to get_fields(). Check
>>>> the documentation for the Model._meta to check its full potential.
>>>>
>>>> Hope it helps!
>>>>
>>>> On Wed, Jun 6, 2018, 07:33 Mikkel Kromann <[email protected]>
>>>> wrote:
>>>>
>>>>> Thanks for the advice, Andréas.
>>>>> But the response is the same:
>>>>>
>>>>>   File "C:\Users\ ... xxxxxxx   ... \items\views.py", line 7, in
>>>>> ItemUpdateView
>>>>>     fields = self.model.fields
>>>>> NameError: name 'self' is not defined
>>>>>
>>>>>
>>>>>
>>>>> As far as I understood, model is an attribute, not a method (though
>>>>> I'm new to Python and Django, so I'm unsure about this).
>>>>> Does attribute/method make a difference in this case?
>>>>>
>>>>> cheers, Mikkel
>>>>> tirsdag den 5. juni 2018 kl. 22.10.31 UTC+2 skrev Andréas Kühne:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> Have you tried self.model? It should be present in all methods in the
>>>>>> class?
>>>>>>
>>>>>> Regards,
>>>>>>
>>>>>> Andréas
>>>>>>
>>>>>> 2018-06-05 21:56 GMT+02:00 Mikkel Kromann <[email protected]>
>>>>>> :
>>>>>>
>>>>>>> Dear Django-users.
>>>>>>>
>>>>>>> I'm slowly working towards a Django "data-warehouse" framework,
>>>>>>> where I can easily add a lot of models (each containing a table with 
>>>>>>> data),
>>>>>>> while sticking to only few reusable views.
>>>>>>>
>>>>>>> I've realised that in urls.py, it is possible to specify the model
>>>>>>> on which the UpdateView is going to do its magic.
>>>>>>> This allows me to use a generic UpdateView (which I called
>>>>>>> ItemUpdateView) and template for all my models, which will save me a 
>>>>>>> ton of
>>>>>>> almost identical lines of code.
>>>>>>>
>>>>>>> However, in the generic ItemUpdateView, I of course need to specify
>>>>>>> the fields of the specific model chosen in urls.py.
>>>>>>> As I ideally only want a few generic views (i.e. ItemCreateView,
>>>>>>> ItemUpdateView, ItemDeleteView and ItemListView), I've chosen to place 
>>>>>>> the
>>>>>>> field array in my model definition, hoping to be able to access it from 
>>>>>>> my
>>>>>>> generic Class Based Views
>>>>>>>
>>>>>>> But how do I access the model attribute in (Item)UpdateView
>>>>>>>
>>>>>>>
>>>>>>> thanks, Mikkel
>>>>>>>
>>>>>>> From views.py
>>>>>>> from django.views.generic import CreateView, ListView, UpdateView,
>>>>>>> DeleteView
>>>>>>>
>>>>>>> class ItemUpdateView(UpdateView):
>>>>>>>     template_name = "item_form.html"
>>>>>>> # How do I access the model attribute of ItemUpdateView as given in
>>>>>>> urls.py?
>>>>>>> # This line below returns the error "NameError: name 'model' not
>>>>>>> defined"
>>>>>>>     fields = model.fields
>>>>>>>
>>>>>>> From urls.py
>>>>>>> from django.urls import path
>>>>>>> from . views import ItemUpdate
>>>>>>> from . models import Region, Location
>>>>>>>
>>>>>>> # Awesome! I can specify the model to be used by ItemUpdateView
>>>>>>> urlpatterns = [
>>>>>>>     path('update/region/<pk>',    ItemUpdateView.as_view(model=
>>>>>>> Region),     name='region_update'),
>>>>>>>     path('update/location/<pk>',  ItemUpdateView.as_view(model=
>>>>>>> Location),   name='location_update'),
>>>>>>> ]
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> From models.py (Region and Location are only two of my tables, I'd
>>>>>>> like to have say 20 or 30 models
>>>>>>> from django.db import models
>>>>>>>
>>>>>>> # Abstract class for our items including common methods, data and
>>>>>>> definitions
>>>>>>> class ItemModel(models.Model):
>>>>>>>
>>>>>>>     fields = [ 'label', 'short', 'descr' ]
>>>>>>>     label   = models.CharField(max_length=10)
>>>>>>>     short   = models.CharField(max_length=15)
>>>>>>>     descr   = models.CharField(max_length=40)
>>>>>>>
>>>>>>>     def __str__(self):
>>>>>>>         return self.short
>>>>>>>
>>>>>>>     class Meta:
>>>>>>>         abstract = True
>>>>>>>
>>>>>>> class Region(ItemModel):
>>>>>>>     fields  = [ 'label', 'short', 'descr' ]
>>>>>>>
>>>>>>> class Location(ItemModel):
>>>>>>>     fields  = [ 'label', 'short', 'descr', 'region' ]
>>>>>>>     region  = models.ForeignKey(Region, on_delete=models.CASCADE)
>>>>>>>
>>>>>>> class Plant(ItemModel):
>>>>>>>     fields  = [ 'label', 'short', 'descr', 'location', 'capex',
>>>>>>> 'opex', 'capacity' ]
>>>>>>>     location= models.ForeignKey(Location, on_delete=models.CASCADE)
>>>>>>>     capex   = models.DecimalField(decimal_places=3, max_digits=8)
>>>>>>>     opex    = models.DecimalField(decimal_places=3, max_digits=8)
>>>>>>>     capacity= models.DecimalField(decimal_places=3, max_digits=8)
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> 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 [email protected].
>>>>>>> To post to this group, send email to [email protected].
>>>>>>> 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/ec4634e5-2279-49a7-9045-21712de87584%40googlegroups.com
>>>>>>> <https://groups.google.com/d/msgid/django-users/ec4634e5-2279-49a7-9045-21712de87584%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>> .
>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>
>>>>>>
>>>>>> --
>>>>> 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 [email protected].
>>>>> To post to this group, send email to [email protected].
>>>>> 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/95db9cca-58ca-4460-ae39-9150bb199bff%40googlegroups.com
>>>>> <https://groups.google.com/d/msgid/django-users/95db9cca-58ca-4460-ae39-9150bb199bff%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>> --
>>> 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 [email protected].
>>> To post to this group, send email to [email protected].
>>> 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/c857567f-dd71-46c1-a05b-787566bfa180%40googlegroups.com
>>> <https://groups.google.com/d/msgid/django-users/c857567f-dd71-46c1-a05b-787566bfa180%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
> 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 [email protected].
> To post to this group, send email to [email protected].
> 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/b6502b29-81e6-449e-894b-16f92ed5e871%40googlegroups.com
> <https://groups.google.com/d/msgid/django-users/b6502b29-81e6-449e-894b-16f92ed5e871%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
-- 
[]'s
Daniel Germano Travieso
Engenharia de Computação UNICAMP

-- 
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 [email protected].
To post to this group, send email to [email protected].
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/CABF8kZOBdggt%2BCJy219QpOGv8BwAkNGRf20X4RuZsJ-xfopXzg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to