I am trying to customize a ploneformgen form by dynamically populating a selection field. I need to parse a file on my filesystem and select certain options based on their date and time. Creating the python script was no brainer but then where do I place the script?
From what I understand, external methods are not the preferred choice in plone 4
I tried to add a python script via ZMI but then I was hit by restricted python and my script would not execute.
I developed an add-on and placed it in the eggs folder and then wrote a python script to call the code from the add-on but unfortunately I was hit again with the same error as previously "You do not have sufficient permissions to view this page". From what I understood, code inside an add-on is not restricted, or?
What would be the best option to achieve the customisation of the form?
If you used a skin script, then yes, that is run as restricted python as well. It is the filesystem-stored equivalent of the ZMI python script.
Best practice is to use a browser view; it is simply a callable object that has a request and context associated to it:
from zope.publisher.browser import BrowserView
class MyBrowserView(BrowserView):
def __call__(self):
request = self.request
context = self.context
# Do something with the request and context
Register this in your configure.zcml:
<browser:view
for="*"
name="mybrowserview"
class=".views.MyBrowserView"
permission="zope2.Public"
/>
after which it'll be available as someobject/##mybrowserview for PloneFormGen.
However, if this is the only thing you are creating a custom package for then by all means use an external method.
Related
I have a pyramid API which has basically three layers.
View -> validates the request and response
Controller -> Does business logic and retrieves things from the DB.
Services -> Makes calls to external third party services.
The services are a class for each external API which will have things like authentication data. This should be a class attribute as it does not change per instance. However, I cannot work out how to make it a class attribute.
Instead I extract the settings in the view request.registry.settings pass it to the controller which then passes it down in the init() for the service. This seems unnecessary.
Obviously I could hard code them in code but that's an awful idea.
Is there a better way?
Pyramid itself does not use global variables, which is what you are asking for when you ask for settings to be available in class-level or module-level attributes. For instance-level stuff, you can just pass the settings from Pyramid into the instance either from the view or from the config.
To get around this, you can always pass data into your models at config-time for your Pyramid app. For example, in your main just pull settings = config.get_settings() and pass some of them to where they need to be. As a general rule, you want to try to pass things around at config-time once, instead of from the view layer all the time.
Finally, a good way to do that without using class-level or module-level attributes is to register instances of your services with your app. pyramid_services library provides one approach to this, but the idea is basically to instantiate an instance of a service for your app, add it to your pyramid registry config.registry.foo = ... and when you do that you can pass in the settings. Later in your view code you can grab the service from there using request.registry.foo and it's already setup for you!
So I have a Django Application that uses a "framework" we have created that includes methods and classes that are known to the user. I want to implement a feature such that the user can write code on the website's provided editor, which would then include this framework library and display the code written.
I am using Django and I am not sure how would I be able to execute the code and display the returning values from the code written by the user.
I have a new job and a huge django project (15 apps, more than 30 loc). It's pretty hard to understand it's architecture from scratch. Are there any techniques to simplify my work in the beginning? sometimes it's even hard to understand where to find a form or a view that I need... thnx in advance.
When I come to this kind of problem I open up a notebook and answer the following:
1. Infrastructure
Server configuration, OS etc
Check out the database type (mysql, postgres, nosql)
External APIS (e.g Facebook Connect)
2. Backend
Write a simple description
Write its input/output from user (try to be thorough; which fields are required and which aren't)
Write its FK and its relation to any other apps (and why)
List down each plugin the app is using. And for what purpose. For example in rails I'd write: 'gem will_paginate - To display guestbook app results on several pages'
3. Frontend
Check out the JS framework
Check the main stylesheet files (for the template)
The main html/haml (etc) files for creating a new template based page.
When you are done doing that. I think you are much more prepared and able go deeper developing/debugging the app. Good luck.
Use this http://packages.python.org/django-extensions/graph_models.html
to generate the Relationship diagrams from the models so that you can visually see how the models are related to each other. This will give you nice idea about the app
1) Try to install the site from scratch. You will find what external apps are needed for the site to run.
2) Reverse engineer. Browse through the site and try to find out what you have to do to change something to that page. Start with the url, look up in urls.py, read the view, check the model. Are there any hints to other processes?
3) Try to write down everything you don't understand, and document the answers for future reference.
I would clone the project so you can mess up endlessly.
Then I would start to reduce the code. "What happens if if just remove this function here?
Also get django debug toolbar:
https://github.com/django-debug-toolbar/django-debug-toolbar
A good terminal debugger is also golden, there are many out there, here is an example:
https://github.com/tomchristie/django-pdb
This allow you to halt the code and even inject and mutate parameters in runtime. Just like GDB in C.
If you use FireFox you can install FireBug on it and when you for example submit ajax form you can see at which url send you request after what you can easily find controller which work with this form data. At chrome this utility embedded by default and call by F12 key.
I have written some test scripts in python which call some apis for a paritcular application and output the results to a database so I can use jasper to report on the results. Currently the scripts are run using a python interpreter, ie double click on the python file that has some parameters and variables modifed within the script that then initiates the tests. I would like to move towards a more user friendly interface so other people can use these test scripts without having to modify the python code. So I am thinking about using django and creating a web page that has check boxes, and if the check box is ticked, then it will execute that particular python test script or a text box that will pass the values to a given variable, for example. I have a few questions around how this might be achieved.
1 - would I need to implement the python code in to the django source code or can I call the python script from the web page served up by django?
2 - If I were to run this from a web page, how could I ensure that if the web page was closed, that the test would continue in the background.
3 - Is there a way to output the status of the test case to a web page and if the web page was closed, for the status to be availble if the web page was reopened?
Many thanks - oli
If you have a python function you can call from a Django django view maybe with a form as parameter input. If you have long running processes you might want to consider a tip from here: How to start a long-running process from a Django view?
from mytests import testfunc
def test_parameter_view(request):
if request.method == 'POST': # If the form has been submitted...
form = ParameterForm(request.POST)
if form.is_valid():
testfunc(form.cleaned_data['parameter']) # <-- Here the actual testing happens
return HttpResponseRedirect(reverse(test_result)) # Redirect after POST
else:
form = ParameterForm()
return render_to_response('test.html', {
'form': form,
})
In your test_result view you can access the test result values from the database.
If the user closes the browser or not doesn't affect server processes that already have been started. And since you write your results to the database they are persistent and can be accessed any time after the test has finished.
If you don't want to port over your scripts into django views, there is another way:
1 - Set up a form with all the options that you want passed to the script
2 - GET or POST the form params and save them to variables using var1 = request.POST['param1'], etc
3 - Use a module called subprocess to execute your script. http://docs.python.org/library/subprocess.html
I have a Django admin interface that is used almost solely as a gui form for making changes to a single postgresql table. There's also a Python script that's currently run manually from the command line whenever a change is made to the database, & I'd like to hook that up so it runs whenever someone hits "save" after making a change to a row of the table via the admin interface. If this was an entry in views.py, it looks like I'd import the script as a module and run its main function from the view (ie, Can Django use "external" python scripts linked to other libraries (NumPy, RPy2...)). I'm not sure, however, how to do this in the admin interface.
How is admin.py similar/different to a regular entry in views.py?
Where do I put the import/call to the external script - somewhere in the model, somewhere in admin.py?
I'm familiar with Python, but am fairly new to (& somewhat mystified by) "web stuff" (ie, frameworks like Django), & I'm not even sure if I'm asking this question very clearly, because I'm still a little fuzzy on the view/model concept ...
Edit: Turns out I had, in fact, found the solution by reading the documentation/tutorial, but assumed there was a difference with admin stuff. As Keith mentioned in the comments, I'm now running into permissions issues, but I guess that's a separate problem. So thanks, & maybe I'll stop second guessing myself ...
Generally, things you want to happen at 'save' time are either
Part of the model.
If so, you override the model's save method: http://docs.djangoproject.com/en/1.3/ref/models/instances/#saving-objects
You can do anything in that save method.
Part of the view function.
If so, you either extend the admin interface (not so easy), or you write your own.
One thing you might consider is defining the save_model method in your ModelAdmin. This will get executed when someone saves from the admin (but not when someone does a save outside of the admin). This approach might depend on what your requirements are, but should give you the necessary hook when doing the save from the admin.
In admin.py
class MyModelAdmin(admin.ModelAdmin):
model = models.MyModel
def save_model(self, request, obj, form, change):
# you can put custom code in here
obj.save()