django app config values storage - django

How should I store parameters for application configuration?
For example. I've application for calculation of taxes in my project. There is few values I need to save once for long time without changes but with possibility to edit them(taxes, payment commissions, etc). Should I create some config.py file or create model config? Maybe there is other way.

If you want to configurate parameters in some calculation, I would go with model object and initial fixture. Because it's stored in database, you can change it anytime.
For example:
class Setting(models.Model):
key = models.CharField(max_length=255, blank=False, null=False, unique=True)
value = models.IntegerField(blank=False, null=False)
description = models.TextField(blank=True, null=True)
def __str__(self):
return self.key
and fixture (https://docs.djangoproject.com/en/1.9/howto/initial-data/):
[
{
"model": "myapp.setting",
"pk": 1,
"fields": {
"key": "[SOME_PARAMETER_KEY]",
"value": "[some value]",
"description": "[some description]"
}
}
]

Related

django icontains doesnt work with line breaks

im using django 2.1.8 and mongodb
model.py
class Article(models.Model):
title = models.CharField("title", default="", max_length=20)
text = models.CharField("comment", default="", max_length=120)
the one object i have
[
{
"id": 1,
"title": "test",
"comment": "there is a
linebreak"
}
]
views.py
a = Article.objects.filter(text__icontains="\r\n").all()
b = Article.objects.filter(text__icontains="there").all()
It finds a but not b.
As long as icontains includes the "\r\n" i can find all things normal. But a user wont search for "\r\n linebreak". how does it work without "\r\n"?

Django one to many between legacy tables with no PK to FK relation

I am using legacy DB tables that I have no control over the tables design.
Table A has an auto_gen ID field as follows:
Table DRAWER (One Side), Table FOLDER (Many Side)
class Drawer(models.Model):
id = models.PositiveIntegerField(primary_key=True, db_column='ID')
fld1 = models.CharField(max_length=1000, db_column='FLD1')
fld2 = models.CharField(max_length=1000, db_column='FLD2')
fld3 = models.CharField(max_length=1000, db_column='FLD3')
def __str__(self):
field_values = []
for field in self._meta.get_fields():
field_values.append(str(getattr(self, field.name, '')))
return ' '.join(field_values)
class Meta:
managed = False
db_table = u'"MySchema"."DRAWER"'
class Folder(models.Model):
id = models.PositiveIntegerField(primary_key=True, db_column='ID')
fld1 = models.CharField(max_length=1000, db_column='FLD1')
fld4 = models.CharField(max_length=1000, db_column='FLD4')
fld5 = models.CharField(max_length=1000, db_column='FLD5')
drawer = models.ForeignKey(to=Drawer, related_name='Drawer.fld1+', on_delete=models.CASCADE, db_constraint=False)
def __str__(self):
field_values = []
for field in self._meta.get_fields():
field_values.append(str(getattr(self, field.name, '')))
return ' '.join(field_values)
class Meta:
managed = False
db_table = u'"MySchema"."FOLDER"'
The ID fields are numeric auto gen. I am trying to use Djano models to establish a one to many relation between Tables DRAWER and FOLDER using fld1. fld1 is unique in Drawer, and many in Folder. I have done this in Java, but so far, it seems that Django won't allow it. Django seems to expect that one side must be a PK? I do realize that Django has many to one (instead of one to many) and followed the documentations ... but it is not working. Please advise if there is a way to do this in Django models framework.
The end result I am looking for in the rest service is something like below, which is what I get from the current JAVA Hibernate Data Rest Service:
{
"ID": 1234,
"FLD1": "xxxxxxxx",
"FLD2": "wertt",
"FLD3": "rtyuio",
folder:[
{
"ID": 5645,
"FLD1": "xxxxxxxx",
"FLD4": "zzzzzzz",
"FLD5": "cccccccc",
},
{
"ID": 5645,
"FLD1": "xxxxxxxx",
"FLD4": "rrrrrrr",
"FLD5": "cccccuuuuuuuuuuccc",
}
.
.
]
I appreciate any help that you can provide.

Django: How to set up a test server with fixtures but Django models containing ForeignKeys?

I'm trying to directly test my client code (with requests module) to call my Django API.
However, I want to automate this.
What I'm trying to do is create a model with test server running.
How am I able to populate my testdb with fixtures if one of my models has a ForeignKey?
class Customer(models.Model):
name = models.CharField(max_length=150)
phone = models.CharField(max_length=12)
email = models.CharField(max_length=250)
class Load(models.Model):
load_id = models.CharField(max_length=100, blank=True)
invoice_id = models.CharField(max_length=100, blank=True)
>customer = models.ForeignKey(Customer, on_delete=models.CASCADE, blank=True, null=True)
notes = models.CharField(max_length=500, blank=True)
carrier = models.ForeignKey(Carrier, on_delete=models.CASCADE, null=True, blank=True)
driver = models.ForeignKey(Driver, on_delete=models.CASCADE, null=True, blank=True)
active = models.BooleanField(default=True)
Edit: I linked the doc pertaining to this question. https://docs.djangoproject.com/en/dev/howto/initial-data/
Per the docs it has the following:
[
# I added the myapp.Band as an example of my issue
{
"model": "myapp.Band",
"pk": 1,
"fields": {
"band_name": "The Beatles"
}
},
{
"model": "myapp.person",
"pk": 1,
"fields": {
"first_name": "John",
"last_name": "Lennon"
}
},
{
"model": "myapp.person",
"pk": 2,
"fields": {
"first_name": "Paul",
"last_name": "McCartney"
# "band": ??? how would I assign?
}
}
]
Have you tried looking at Natural Keys: https://docs.djangoproject.com/en/dev/topics/serialization/#natural-keys
If you have the fixture created, update your database settings and run the loaddata command to load the fixture to the database.
Fixtures are often over-rated compared to using Factoryboy and Faker to generate test objects, including large batches of them for testing list-views and Django-filter views. I found this article extremely helpful in explaining how to combine them. The pain with fixtures comes when you add or remove fields from your models and forget to regenerate your fixtures. Or worse, if you leak information that really shouldn't have been made publicly accessible.
One warning - don't test factories from the manage.py shell. They automatically save the objects they generate! Instead write a test to test the factories. To avoid this mistake I put all my factories in one pseudo-app called fakery and in the __init.py__ file above the factory codes,
import sys
if len( sys.argv) >= 2 and sys.argv[1].find('shell') >= 0:
print("\nWARNING -- don't forget that Factories will save all objects they create!\n")
so if you import any of them into a shell, you see a warning.

How can I load fixtures with circular foreign keys in django?

I have a model for categories, which contains a circular foreign key. I dumped all the data from this model and I created a data migration with django-south for loading them into a different DBMS, but I having a lot of problem doing it, because of this circular dependency.
This is the model I'm referring:
class Category(MPTTModel):
name = models.CharField(_('name'), max_length=50, unique=True)
parent = models.ForeignKey('self', null=True, blank=True, related_name='categories')
description = models.TextField(_('description'), blank=True, null=True)
created_on = models.DateTimeField(auto_now_add = True, default=date.today())
updated_on = models.DateTimeField(auto_now = True, default=date.today())
def __unicode__(self):
return "%s" %(self.name)
class Meta:
verbose_name = _('category')
verbose_name_plural= _('categories')
Thanks to this post I could find a solution. Temporarily disable foreign key checks while you load in data is the best feasible solution for this issues.
Since Django doesn't provide a way to do this, we should execute raw sql code.
So, I created a data migration with django-south and the rest is in the code below:
class Migration(DataMigration):
def forwards(self, orm):
#~ Disable foreign key checks during fixture loading
from django.db import connections, DEFAULT_DB_ALIAS
connection = connections[DEFAULT_DB_ALIAS]
if 'mysql' in connection.settings_dict['ENGINE']:
cursor = connection.cursor()
cursor.execute('SET foreign_key_checks = 0')
#~ Load fixture
from django.core.management import call_command
call_command('loaddata', 'categories_fixture.json', verbosity=0)
#~ Enable foreign key checks after fixture loading
if 'mysql' in connection.settings_dict['ENGINE']:
cursor = connection.cursor()
cursor.execute('SET foreign_key_checks = 1')
connection.close()
The quick answer is that you need to disable foreign key constraints while loading.
There's a patch for Django, but it may or may not be in the version you are using:
https://code.djangoproject.com/ticket/3615
Alternatively, don't use fixtures, use SQL: https://docs.djangoproject.com/en/dev/howto/initial-data/#providing-initial-sql-data
The upside is that you can do anything in a model SQL file that you can do in SQL. The downside is that it is no longer database-agnostic, depending on the SQL you are using.
Answering in 2016. Django supports loading interdependent fixtures, simply add them to the same file
// fixtures.json
[
{
"model": "A",
"pk": 1100,
"fields": {
"bfk": 1000,
}
},
{
"model": "B",
"pk": 1000,
"fields": {
"Afk": 1100
}
}
]

Django json serialization problem

I am having difficulty serializing a django object. The problem is that there are foreign keys. I want the serialization to have data from the referenced object, not just the index.
For example, I would like the sponsor data field to say "sponsor.last_name, sponsor.first_name" rather than "13".
How can I fix my serialization?
json data:
{"totalCount":"2","activities":[{"pk": 1, "model": "app.activity", "fields": {"activity_date": "2010-12-20", "description": "my activity", "sponsor": 13, "location": 1, ....
model code:
class Activity(models.Model):
activity_date = models.DateField()
description = models.CharField(max_length=200)
sponsor = models.ForeignKey(Sponsor)
location = models.ForeignKey(Location)
class Sponsor(models.Model):
last_name = models.CharField(max_length=20)
first_name= models.CharField(max_length=20)
specialty = models.CharField(max_length=100)
class Location(models.Model):
location_num = models.IntegerField(primary_key=True)
location_name = models.CharField(max_length=100)
def activityJSON(request):
activities = Activity.objects.all()
total = activities.count()
activities_json = serializers.serialize("json", activities)
data = "{\"totalCount\":\"%s\",\"activities\":%s}" % (total, activities_json)
return HttpResponse(data, mimetype="application/json")
Add relations to the serializer like this:
activities_json = serializers.serialize("json", activities, relations=('sponsor',))
Then all you need is:
return HttpResponse(activities_json, mimetype="application/json")
Then make sure you also have the django library wadofstuff installed.
Hope this helps!
The docs seem to explain exactly how to do this. Read the part about serialization of natural keys.
This small lib is very handy with django : http://code.google.com/p/wadofstuff/wiki/DjangoFullSerializers
It allows more customisation than the standard encoder.
any2any also contains serializers allowing to customize completely the output format :
check the docs
repo on bitbucket
or on pypi