django kept previous data in database - python

I am using postgresql_psycopg2 database in one of my django powered website.Previously i have used sqlite3 in test basis,but i have left it because now i am going to live my project in server,so we know that in sqlite3 if we edit model,then we have to delete the whole database,cause as far as i know ,sqlite3 don't provide any database update service or migration service.
So i have switched in to the postgresql_psycopg2.As i am new in django,now how can i kept my previous data after updating model.
for example i have a
Photo model something like this,
class Photo(models.Model):
name = models.CharField(max_length = 100)
photo = models.ImageField(upload_to = 'photos', blank=False,null=True)
approved = models.BooleanField(default = False)
approved_time = models.DateTimeField(auto_now=True,null=True,blank=True)
uploaded_time = models.DateTimeField()
description = models.CharField(max_length = 500 , blank = False , null = True)
keyword = models.CharField(max_length = 500 , blank = False , null = True)
user = models.ForeignKey(User)
now i want to add a extra field in my Photo model,
class Photo(models.Model):
name = models.CharField(max_length = 100)
photo = models.ImageField(upload_to = 'photos', blank=False,null=True)
approved = models.BooleanField(default = False)
approved_time = models.DateTimeField(auto_now=True,null=True,blank=True)
uploaded_time = models.DateTimeField()
description = models.CharField(max_length = 500 , blank = False , null = True)
keyword = models.CharField(max_length = 500 , blank = False , null = True)
user = models.ForeignKey(User)
#new field added
photo_dpi = models.CharField(max_length = 500 , blank = False , null = True)
now how can i kept my previous data after adding a new field.

You should use migrations to edit database structure:
https://docs.djangoproject.com/en/1.7/topics/migrations/
Or, if your django version is less than 1.7, South package:
http://south.readthedocs.org/en/latest/

Just run makemigrations and migrate commands:
python manage.py makemigrations
python manage.py migrate
UPDATE: makemigrations/migrate commands are available since django 1.7.
As #eugene-soldatov mentioned in his answer for django 1.5 you can use the South app.
Another option is to alter the table manually by executing the following SQL query:
echo "ALTER TABLE myapp_photo ADD COLUMN photo_dpi VARCHAR(500) NULL;" | python manage.py dbshell
Where myapp is the name of your application.

Related

Django DurationField format options

Good evening. I have a question do you have some snippet for DurationField to show it in django admin in format HH:MM? I can't find anything over the internet and 3rd party apps doesn't work in new django. Thank you for help.
Model:
from django.db import models
# Create your models here.
class Aircraft (models.Model):
id = models.AutoField(primary_key=True)
registration = models.CharField(max_length=7)
#hours to maintenance
hours_to_maintenance = models.DateTimeField(help_text = "test", null = True)
#current hours
ch = models.TimeField(help_text = "test", null = True)
#rm = models.IntegerField(help_text = "test", null = True)
added_by = models.ForeignKey('auth.User', on_delete = models.CASCADE,)
def __str__(self):
return self.registration

Django not updating Database

I am working on a Django 1.10 project with python 3.
This is my models.py:
# /Multiple choices/
SEX_CHOICES = (('M', 'Male'),
('F', 'Female')
)
ZONE_CHOICES = (('D', 'Départementale'),
('N', 'Nationale')
)
# /Extension of User model/
class Profile(models.Model):
user = models.OneToOneField(User, related_name='profile')
sex = models.CharField(max_length=1, choices=SEX_CHOICES, default='M')
departementNumber = models.PositiveSmallIntegerField(default=88, validators=[MaxValueValidator(101)])
departement = models.CharField(max_length=200)
zone = models.CharField(max_length=1, choices=ZONE_CHOICES, default='D')
receivedApprove = models.PositiveSmallIntegerField(default=0)
receivedDescription = models.PositiveSmallIntegerField(default=0)
receivedDesapprove = models.PositiveSmallIntegerField(default=0)
givenApprove = models.PositiveSmallIntegerField(default=0)
givenDescription = models.PositiveSmallIntegerField(default=0)
givenDisapprove = models.PositiveSmallIntegerField(default=0)
def __str__(self):
return self.user.username
What I am trying to do is to take some users information and complete their profile. Here is what i did in my views.py :
user_id = request.user
firstname = form.cleaned_data['firstname']
lastname = form.cleaned_data['lastname']
email = form.cleaned_data['email']
sex = form2.cleaned_data['sex']
departementNumber = form2.cleaned_data['departementNumber']
zone = form2.cleaned_data['zone']
At this stage, everything is working fine. The problem start when I try to update my model. User object is updating correctly :
upd = User.objects.filter(id=user_id.id).update(first_name=firstname, last_name=lastname, email=email)
But Profile is not updating :
upd2 = Profile.objects.filter(id=user_id.id).update(sex=sex, departementNumber=departementNumber, departement=depName, zone=zone)
And I have not a single warning or error message.
I think the problem is in Profile model. You should add primary_key=True to user field, in order to get the same id as the actual User.
e.g.
user = models.OneToOneField(User, related_name='profile', primary_key=True)
I will add another situation in which the database does not update when using the update() method.
order = Order.objects.filter(id=d['id']).first()
Order.objects.filter(id=d['id']).update(currency=d['currency'])
# further code using order
In this situation the order row is referenced in the first line of code and the update() in line 2 does not work. I don't know the internal reason why line 2 does not update the row in the DB, but from a logical standpoint one should anyway put line 1 after line 2 (which solves it). However if making several code changes this can occur and it looks at first unintuitive why the update() returns '1' even though no update of the DB row happened.

What is the default type for a user in Django?

I have a MySQL database object that stores concerts that a User plans to attend on a certain date. Since each concert entry needs to be associated with a User, I added a foreign key field for User as an attribute of the Concert model. Here is the complete model:
class Concert(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE)
concert_name = models.CharField(max_length = 120, blank = True, null = True)
venue = models.CharField(max_length = 120, blank = True, null = True)
city = models.CharField(max_length = 120, blank = True, null = True)
state = models.CharField(max_length = 120, blank = True, null = True)
country = models.CharField(max_length = 120, blank = True, null = True)
timestamp = models.DateTimeField(auto_now_add = True, auto_now = False)
updated = models.DateTimeField(auto_now_add = False, auto_now = True)
When I try to make migrations to the DB, I get a message saying: You are trying to add a non-nullable field 'user' to concert with out a default; s essentially saying that the already populated rows need to have a value. I found this SO post which seemed to be addressing a similar issue, but the default value suggested in the solution is for a charfield and I don't think that would really apply in this situation. How should I go about setting the default value of the User object?
You can use null=True:
user = models.ForeignKey(User, null=True)
Although if you look at your db actual model, you cannot see an actual Foreign Key, when you put models.ForeignKey(User) in your model you can see in your db a user_id with references, but the relation needed exists so you can make it's null=True as a default.

How to use Django join

Hi I am making a backend server in Django for storing user data from an app.
Below are my models.
class Subscriber(models.Model):
subId = models.IntegerField(max_length=20,unique=True,blank=False)
Name = models.CharField(max_length=25,blank=True)
class SMS(models.Model):
subscriberId = models.ForeignKey(Subscriber, null=False)
epochTime = models.IntegerField(null = False)
time = models.CharField(max_length= 250 ,blank = False)
class Call(models.Model):
subscriberId = models.ForeignKey(Subscriber, null=True)
epochTime = models.IntegerField(null = False)
time = models.CharField(max_length= 50 ,blank = False)
Date = models.CharField(max_length= 50 ,blank = False)
I need to write a Django query which I will give subscriberId and Django will return me to use the data for that user from Call and SMS (basically wants to use Join ).
earlier I have applied this in mysql.
select * from Server_Text JOIN (Server_Call) ON (Server_SMS.subscriberId_id = 11 and Server_Call.subscriberId_id = 11) ;
where Server is my mysql Database.
You shouldn't think in terms of joins and sql queries when you're using Django; the point is that the model layer abstracts these away. You just want to get the Subscriber, then follow the relationships to get the SMS and Call info:
subscriber = Subscriber.objects.get(subId=my_subscriber_id)
print subscriber.sms_set.all() # all SMSs for that subscriber
print subscriber.call_set.all() # all Calls for that subscriber
If you're doing this a lot, you can make it a bit more efficient by using prefetch_related('sms', 'call') in the initial query.

Django mysql table name did not validate

I added classes to Django app model to create mysql tables. I have 'downloads' table, and 'downloads' column in 'songs' table.
When i want to sync db, Django returns me error:
CommandError: One or more models did not validate:
mp3mid.downloads: Reverse query name for field 'song' clashes with field 'songs.downloads'. Add a related_name argument to the definition for 'song'.
Why it's impossible to give same name to table and column?
this is my models.py:
from django_evolution.mutations import *
from django.db import models
class singers(models.Model):
name = models.CharField(max_length = 255)
category = models.ForeignKey(categories)
class songs(models.Model):
name = models.CharField(max_length = 255)
singer = models.ForeignKey(singers)
downloads = models.IntegerField(max_length = 11)
exclusive = models.BooleanField(default = 0)
hit = models.BooleanField(default = 0)
date = models.DateTimeField(auto_now_add = True)
link = models.CharField(max_length = 255)
class downloads(models.Model):
song = models.ForeignKey(songs)
date = models.DateTimeField(auto_now_add = True)
Django allows you to make queries that span relationships.
In your case, the foreign key from downloads to songs means you could usually make queries that follow the relationship backwards from song to downloads:
from datetime import datetime
# fetch all songs with a download with a date on or after 2013-05-01.
songs = song.objects.filter(downloads__date__gte=datetime(2013,5,1))
However, you can't do that in this case, because downloads clashes with your songs.downloads field.
You have a couple of options. First, you can set related_name for your foreign key, as suggested by your error message.
class downloads(models.Model):
song = models.ForeignKey(songs, related_name="related_downloads")
Or, you can rename your song.downloads field.
class songs(models.Model):
...
num_downloads = models.IntegerField(max_length = 11)
As an aside, I recommend you rename your models to Singer, Song and Download (capitalized, singular instead of plural), to follow the Django convention.

Categories