Thanks Daniel. I actually tried to implement it in the __init__ but it didn't work. I'll read through your explanation more carefully - I'm sure I could use a bit better understanding on the ways of Python and Django :) Again, thank you for your very useful replies
cheers, Mikkel torsdag den 7. juni 2018 kl. 00.24.03 UTC+2 skrev Daniel Germano Travieso: > > 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] > <javascript:>> 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] <javascript:>. >> To post to this group, send email to [email protected] >> <javascript:>. >> 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/21845118-c9d0-495e-9aa9-921a7ac1bf2a%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.

