I want to have some database stored settings for my Django app - just some key-value pairs. Does Django have a conventional way of doing this / something built in for it, or should I implement it myself?
class Setting(models.Model):
key = models.TextField()
value = models.TextField()
Of course, I'd want to be able to store any data type for keys and values. Perhaps I could use pickle to coerce them all into strings.
I've just been playing with the django-satchmo e-store application. Satchmo uses satchmo-livesettings or just livesettings to achieve this goal. In addition to that it is possible to change the settings using the admin interface.
The only problem is that I didn't find a tutorial on how to use livesettings. But if you browse the satchmo code, you'll see how it works.
Here is my example
from livesettings import config_register, StringValue, PositiveIntegerValue
SHOP_GROUP = ConfigurationGroup('SHOP', ('ShirtSale Shop Settings'), ordering=0)
CHARGE_PORTO = config_register(
BooleanValue(SHOP_GROUP,
'CHARGE_PORTO',
description = ('Porto Erheben?'),
help_text = ("Wird bei Bestellungen zusaetzlich ein Porto erhoben?"),
default = True))
I've included those lines in the config.py file. To execute this file it was necessary to:
import config
in the admin.py file (I'm wondering whether this is necessary)
In order to access the settings I've included the following to the urls.py file:
(r'^settings/', include('livesettings.urls')),
Related
I have the following model for my students to upload their tasks to an application that I am creating, but I have a problem, I need to pass an instance of the model between views, but since it is not serializable, I can not save it in a session attribute. Keep in mind that in one view I create the object without saving it in the database and in the other I perform operations with the object and finally I save it. Any idea how I can do this?
from gdstorage.storage import GoogleDriveStorage
gd_storage = GoogleDriveStorage()
class Homework(models.Model):
code = models.AutoField(primary_key=True)
student = models.ForeignKey('Student', on_delete=models.PROTECT)
title = models.CharField(unique=True, max_length=100)
attached_file = models.FileField(upload_to='files/homeworks/', validators=[validate_file_size], storage=gd_storage)
As #dirkgroten says, you can add an additional field to your model that is called status and by default assign it the value of temporary. In addition to this you can review the package code.
Finally to delete a file in Google Drive as a storage backend is very simple. Use the following
gd_storage.delete(name_file)
So change in the code of #dirkgroten
from django.core.files.storage import default_storage
#receiver (post_delete, sender=Homework)
def remove_file (sender, instance, **kwargs):
if instance.attached_file is not None:
gd_storage.delete(instance.attached_file.name)
The only way to keep "state" between views is to save to the database (or other permanent storage). That's what the session does for you.
If you can't serialise to save in the session, then you have no alternative but to save a temporary object to the database. You could mark it as temporary and add a timestamp. And in the next view mark it as committed. And if needed clean up once in a while, removing old temporary objects.
To remove the associated file with old temporary objects, you can add a signal handler for the post_delete signal:
from django.core.files.storage import default_storage
#receiver(post_delete, sender=Homework)
def remove_file(sender, instance, **kwargs)
path = instance.attached_file.name
if path:
default_storage.delete(path)
This is my first question so I will do my best to conform to the question guidelines. I'm also learning how to code so please ELI5.
I'm working on a django project that parses XML to django models. Specifically Podcast XMLs.
I currently have this code in my model:
from django.db import models
import feedparser
class Channel(models.Model):
channel_title = models.CharField(max_length=100)
def __str__(self):
return self.channel_title
class Item(models.Model):
channel = models.ForeignKey(Channel, on_delete=models.CASCADE)
item_title = models.CharField(max_length=100)
def __str__(self):
return self.item_title
radiolab = feedparser.parse('radiolab.xml')
if Channel.objects.filter(channel_title = 'Radiolab').exists():
pass
else:
channel_title= radiolab.feed.title
a = Channel.objects.create(channel_title=channel_title)
a.save()
for episode in radiolab.entries:
item_title = episode.title
channel_title = Channel.objects.get(channel_title="Radiolab")
b = Item.objects.create(channel=channel_title, item_title=item_title)
b.save()
radiolab.xml is a feed I've saved locally from Radiolab Podcast Feed.
Because this code is run whenever I python manage.py runserver, the parsed xml content is sent to my database just like I want to but this happens every time I runserver, meaning duplicate records.
I'd love some help in finding a way to make this happen just once and also a DRY mechanism for adding different feeds so they're parsed and saved to database preferably with the feed url submitted via forms.
If you don't want it run every time, don't put it in models.py. The only thing that belongs there are the model definitions themselves.
Stuff that happens in response to a user action on the site goes in a view. Or, if you want this to be done from the admin site, it should go in the admin.py file.
I read user image in BLOB file, but i want save it to image format in django model.
How can i convert this file to image file(.jpeg) and save it in django models.ImageField?
I use python 2.7 and django 1.9.
my model is:
class Staff(models.Model):
user = models.ForeignKey(User)
cn = models.CharField(max_length=100)
new_comer = models.NullBooleanField()
change_position = models.NullBooleanField()
change_manager = models.NullBooleanField()
acting = models.NullBooleanField()
expelled = models.NullBooleanField()
active = models.NullBooleanField()
avatar = models.ImageField(upload_to='/images/')
Please help me...
You need to try something like this.
import io
from django.core.files.base import File
# Set values of your model filed.
staff_instance = Staff()
staff_instance.user = user_instance
...
...
with io.BytesIO(blob_file) as stream:
django_file = File(stream)
staff_instance.avatar.save(some_file_name, django_file)
staff_instance.save()
I assume that blob is a byte array of the file.
To make it a file i need to convert it to a stream.
Thus I thought BytesIO would be a good choice.
You can directly save file to disk but if you want django to upload it to your upload_to directory, you need to use django.core.files.base.File class.
When you run django.core.files.base() method file will be saved to desired directory.
I guess you will use this for an data migration process, not in a view.
If this is the case than you could put this code at a django command.
Then you can use any django and project related resources.
Let me know if it helps.
Im using django admindocs for documentation and the basic functionality works nicely (I can access the doc pages, models are listed an documented, help_text is included, etc.).
Unfortunately, reStructuredText markup in docstrings is completely ignored, e.g.
Hyperlinks are not converted to hyperlinks
Bullet Lists are no bullet lists
Django markups such as :model:appname.ModelName are not resolved
I'm using the Development Trunk Version of Django (1.7)
Here is an example of a docstring I'm using:
class Adresse(models.Model):
u"""Postanschrift
Wird für
- Organisationen
- Personen
genutzt.
Siehe auch https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#generic-relations
"""
object_id = models.PositiveIntegerField()
content_type = models.ForeignKey(ContentType)
of = generic.GenericForeignKey('content_type', 'object_id' )
...
When I paste the above docstring content into a rest editor (I used http://rst.ninjs.org/), everything works as expected.
The conversion works for docstrings documenting methods, e.g.
def my_method(self):
"""Docstring Heading
1. Listitem 1
2. Listitem 2
refers to :model:`personen.Person`
"""
pass
ist correctly converted.
I'm sure, I missed something very obvious, didn't I?
Then the admindocs module's behavior is the same as in Django 1.4.
To auto-generate navigatable docs from your python files, Python Sphinx https://www.sphinx-doc.org may be a better way, by putting the generates files in another pseudostatic folder.
To do that copy the sphinx docs to a template folder and add a custom urls(..) and view that provides access to the files with restrictions set to staff only (for instance via the canonical decorators login_required and user_pases_test.
Other solutions:
Unfortunately the documentation regarding the rst-usage is somewhat lacking, such as the settings.py parameter RESTRUCTUREDTEXT_FILTER_SETTINGS.
Reassure yourself that in order to activate these filters, django.contrib.markup' is added to your INSTALLED_APPS setting in your settings.py and {% load markup %} in the template.
You should have docutils installed. You will not receive errors if it is not installed.
When using linux with bash, enter:
if [[ -z `pip freeze | grep docutils` ]]; then sudo easy_install docutils;fi;
Directly rendering the reStructuredText:
from django import template
class Adresse(models.Model):
doc = u"""Postanschrift
Wird für
- Organisationen
- Personen
"""
t = template.Template('{% load markup %}{{ contentstr|restructuredtext }}')
c = template.Context({'contentstr': doc})
__doc__ = t.render(c)
You could do this automated by looping through all [relevant] models and their __docs__ attribute to subsequently render the string as reStructuredText as follows:
from django.conf import settings
from django.db.models import get_app, get_models
from django import template
for appname in settings.INSTALLED_APPS:
app = get_app(appname )
for model in get_models(app):
if hasattr(model, '__doc__') and model.__doc__ != "":
t = template.Template('{% load markup %}{{ contentstr|restructuredtext }}')
c = template.Context({'contentstr': model.__doc__})
model.__doc__ = t.render(c)
Can I add a custom restriction for the folder contents in Plone 4.1. Eg. Restrict the folder to contain only files with extensions like *.doc, *.pdf
I am aware of the general restrictions like file/ folder/ page / image which is available in Plone
Not without additional development; you'd have to extend the File type with a validator to restrict the mime types allowed.
Without going into the full detail (try for yourself and ask more questions here on SO if you get stuck), here are the various moving parts I'd implement if I were faced with this problem:
Create a new IValidator class to check for allowed content types:
from zope.interface import implements
from Products.validation.interfaces.IValidator import IValidator
class LocalContentTypesValidator(object):
implements(IValidator)
def __init__(self, name, title='', description='')
self.name = name
self.title = title or name
self.description = description
def __call__(value, *args, **kwargs):
instance = kwargs.get('instance', None)
field = kwargs.get('field', None)
# Get your list of content types from the aq_parent of the instance
# Verify that the value (*usually* a python file object)
# I suspect you have to do some content type sniffing here
# Return True if the content type is allowed, or an error message
Register an instance of your validotor with the register:
from Products.validation.config import validation
validation.register(LocalContentTypesValidator('checkLocalContentTypes'))
Create a new subclass of the ATContentTypes ATFile class, with a copy of the baseclass schema, to add the validator to it's validation chain:
from Products.ATContentTypes.content.file import ATFile, ATFileSchema
Schema = ATFileSchema.schema.copy()
Schema['file'].validators = schema['file'].validators + (
'checkLocalContentTypes',)
class ContentTypeRestrictedFile(ATFile):
schema = Schema
# Everything else you need for a custom Archetype
or just alter the ATFile schema itself if you want this to apply to all File objects in your deployment:
from Products.ATContentTypes.content.file import ATFileSchema
ATFileSchema['file'].validators = ATFileSchema['file'].validators + (
'checkLocalContentTypes',)
Add a field to Folders or a custom sub-class to store a list of locally allowed content types. I'd probably use archetypes.schemaextender for this. There is plenty of documentation on this these days, WebLion has a nice tutorial for example.
You'd have to make a policy decision on how you let people restrict mime-types here of course; wildcarding, free-form text, a vocabulary, etc.