In need of some dire help with setting up relationships in my django model and views.
Just wanted to say thank you! before anyone takes a deep dive below!
Working on an application were I have a One to Many relationship where I have many Products and a few particular products will be related to only one Website.
One of the biggest problems am experiencing is when I try to add a foreign key to my Website Model I get this error:
? The field 'Product.website' does not have a default specified, yet is NOT NULL.
? Since you are adding this field, you MUST specify a default
? value to use for existing rows. Would you like to:
? 1. Quit now, and add a default to the field in models.py
? 2. Specify a one-off value to use for existing columns now
I tried to use this solution here:
Django South - Create Not Null ForeignKey
But to no avail, didnt know what to do after Step #4 and I just got lost regardless.
Models.py in my product_extend app
Product Model:
class Product(models.Model):
"""
The product structure for the application, the products we scrap from sites will model this and save directly into the tables.
"""
product_name = models.CharField(max_length=254, verbose_name=_('Name'), null=True, blank=True)
product_price = CurrencyField( verbose_name=_('Unit price') )
product_slug_url = models.URLField(max_length=200, null=True, blank=True)
product_category = models.CharField(max_length=254, blank=True, null=True)
product_img = models.ImageField('Product Image', upload_to='product_images', null=True, blank=True)
product_website_url = models.URLField(max_length=200, null=True, blank=True)
product_website_name = models.CharField(max_length=254, blank=True, null=True)
#For Admin Purposes, to keep track of new and old items in the database by administrative users
date_added = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date added'))
last_modified = models.DateTimeField(auto_now=True, null=True, blank=True, verbose_name=_('Last modified') )
#For Admin Purposes, to make sure an item is active by administrative users
active = models.BooleanField(default=True, verbose_name=_('Active') )
# Foreign Key
website = models.ForeignKey(Website, null=True, related_name='website_to_product')
Website Model
class Website(models.Model):
name = models.CharField(max_length=254, blank=True, null=True, unique=True)
description = models.TextField(null=True, blank=True)
website_slug = models.SlugField(verbose_name=_('Website Slug'), unique=True)
site_logo = models.ImageField('Websites Logo', upload_to='website_logo_images', null=True, blank=True)
menswear = models.BooleanField(default=False, verbose_name=_('Menswear'))
womenswear = models.BooleanField(default=False, verbose_name=_('Womenswear'))
active = models.BooleanField(default=True, verbose_name=_('Active'))
Edit
I shortened this question in an effort to make it more comprehensible and split the second part as another question:
Django 1.6: Displaying a particular models Objects in another template
Is it right to say that when you do the migration, both Product and Websites already exist in models.py? If that is the case, a workaround would be to enter a random value for this
? 2. Specify a one-off value to use for existing columns now
Or you may for the time being set the null to be true. Then after you created the foreign key and added the key values for the existing rows. You can re-set it to be false. Then run the migration process as in https://stackoverflow.com/a/22617012/2774853:
Step 6. Run ./manage.py schemamigration <app> --auto
Step 7. Run ./manage.py migrate <app>
Hope it helps.
Related
In my models, I added the class Source:
class Source(models.Model):
profile = models.ForeignKey('Profile', on_delete=models.CASCADE, null=True, default=False, blank=True, related_name='+')
project= models.ForeignKey('Project', on_delete=models.CASCADE, null=True, default=False, blank=True, related_name='+')
team = models.ForeignKey('Team', on_delete=models.CASCADE, null=True, default=False, blank=True, related_name='+')
department = models.ForeignKey('Department', on_delete=models.CASCADE, default=False, blank=True, null=True, related_name='+')
def __str__(self):
return str(self.id)
For testing purposes, I added a few entries for posts in the Django admin page,
and then went back into my classes: Post, Profile, Department, Team, and Project, and added:
sourceID = models.ForeignKey('Source', default='1', on_delete=models.CASCADE, related_name='+', null=False)
for each class.
My problem is that when I go in the Django admin page to alter the database (i.e. create a new post) I get the following error:
Also, when I go to migrate my changes, I keep getting this warning:
HINT: Configure the DEFAULT_AUTO_FIELD setting or the LeadsConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.
I would like to be able to create new entries in my database without the operational error. I've tried changing the null value = True, but this is counterintuitive and doesn't yield any change, surprisingly. I think the best way would be to delete the whole database, which I've tried to research and only found MYSql code solutions. What is the best course of action?
I am currently working on django 2.0.2 admin page. I have three tables, which are 'metabolites', 'gene' and 'reactions.' The structure of each class is defined as below:
class Genes(models.Model):
id = models.CharField(primary_key=True, max_length=255)
name = models.CharField(max_length=255, blank=True, null=True)
notes = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'Genes'
class Metabolites(models.Model):
id = models.CharField(primary_key=True, max_length=255)
name = models.CharField(max_length=255, blank=True, null=True)
compartment = models.CharField(max_length=255, blank=True, null=True)
charge = models.CharField(max_length=255, blank=True, null=True)
formula = models.CharField(max_length=255, blank=True, null=True)
notes = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'Metabolites'
class Reactions(models.Model):
id = models.CharField(max_length=255, primary_key=True)
name = models.CharField(max_length=255, blank=True, null=True)
metabolites = models.TextField(blank=True, null=True)
lower_bound = models.CharField(max_length=255, blank=True, null=True)
upper_bound = models.CharField(max_length=255, blank=True, null=True)
gene_reaction_rule = models.TextField(blank=True, null=True)
subsystem = models.CharField(max_length=255, blank=True, null=True)
notes = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'Reactions'
As you can see, the 'reaction' class also included 'metabolites' component. A typically reaction actually involved more than two metabolites. What I want to do is, create a search field on the admin page(not the page of each class), and when I type in the reaction id, the searching result can display the reaction and all the involved metabolites, and when I type in a metabolites, the searching result can display this metabolite's information and all reactions this metabolites involved.
Is that possible? Can somebody tell me how to do this?
Thank you for helping me!
EDIT:
This describes the "old school" way of accomplishing this. This appears to be a use case for django's many to many fields. I have not run into this need in my project; so, I have not, yet, studied up the many to many capabilities in django. I recommend reading the django docs for how to use many to many fields.
The way described here will accomplish the desired connections in the data. However, I suspect that the django admin will be easier and more straightforward to set up using a many to many field.
end edit
You want to make another model for metabolites_in_reaction that only contains its own primary key, a foreign key to the reaction and foreign key to metabolites.
class ReactionMetabolites(models.Model):
reaction = models.ForeignKey(Reactions, on_delete=models.CASCADE)
metabolite = models.ForeignKey(Metabolites, on_delete=models.CASCADE)
A many to many field may also be appropriate here; I have not really figured out the many to many fields yet.
Edit 2:
After making these changes in your models, you will need to make and apply migrations to apply the changes to your database.
python manage.py makemigrations
python manage.py migrate
I went to add a text field to a model in my django app, made, applied my migrations then all of a sudden, I have tests failing left and right. Turns out, the migration decided to drop a field that still exists in my model.
Before going on, some of the relevant code. First, the effected model:
class CandidateProfile(models.Model):
user_profile = models.ForeignKey(UserProfile, related_name="candidate_profile", null=True, blank=True)
facebook_url = models.CharField(max_length=200, default="")
website = models.CharField(max_length=200, default="")
primary_email = models.CharField(max_length=100, default="")
party = models.ForeignKey(PoliticalParty, related_name="candidate_party", null=True, blank=True)
uploaded_picture = models.CharField(max_length=200, default="")
ref_id = models.CharField(db_index=True, max_length=50, default="")
create_date = models.DateTimeField(auto_now_add=True)
update_date = models.DateTimeField(auto_now=True)
The field I added was facebook_url. Prior to this migration, app working, tests passing, etc. The migration that was generated is:
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='candidateprofile',
name='party',
),
migrations.AddField(
model_name='candidateprofile',
name='facebook_url',
field=models.CharField(default=b'', max_length=200),
),
]
The fix itself is simple enough, I can roll back my migration, and manually remove the migrations.RemoveField. Unit tests did what they were supposed to do in letting me know I screwed something up, but I still get worried about something like this getting through to production, losing data and having to restore from a backup.
My question is: why does Django think that the field should be removed even though, it's clearly present as a foreign key in the model?
Edit: After the field was deleted, I tried changing properties on the party attribute to see if whatever diff-ing mechanism Django uses will pick it up. No dice, changing related_name, null, or blank didn't do anything. Running makemigrations detected no changes.
Also, foreign key model for reference:
class PoliticalParty(models.Model):
name = models.CharField(max_length="100")
full_name = models.CharField(max_length="255")
abbreviation = models.CharField(max_length="20")
ref_id = models.CharField(max_length="50", default="", db_index=True)
create_date = models.DateTimeField(auto_now_add=True)
update_date = models.DateTimeField(auto_now=True)
My guess is that you 'shadowed' the field, by creating an attribute or method with the same name.
class CandidateProfile(models.Model):
party = models.ForeignKey(PoliticalParty, related_name="candidate_party", null=True, blank=True)
def party(self):
"""This method will replace the model field"""
return ''
If you didn't do this, then please try to provide instructions that can recreate the issue (preferably with the latest point release 1.8.7). Dropping an existing field is a very serious data loss issue, and the Django developers would take it very seriously.
I am creating a Django Application, and my models.py is :
class Registration(models.Model):
uid = models.AutoField(primary_key=True, default=0)
uname = models.CharField(max_length=100, blank=False, null=False)
upassword = models.CharField(max_length=100, blank=False, null=False)
uphone = models.IntegerField(blank=True, null=True)
uhid = models.ForeignKey('Hood', blank=False, null=False, default='ABC')
uemail = models.EmailField(blank=False, null=False, default='abc402#nyu.edu')
uintro = models.TextField(null=True, blank=True)
uphoto = models.ImageField(upload_to='', blank=False, null=False, default='static/img/natural_join_is_inner_join.png')
uhood = models.CharField(max_length=10, null=True)
uaddress = models.CharField(max_length=100, default='ABC')
# django automatically uses the media root which you have declared in your settings, define that to `upload_to`
def __unicode__(self):
return self.uname
I then run the following commands:
python manage.py makemigrations
python manage.py migrate
But it is showing me an error:
multiple default values specified for column "uid" of table
"registration_registration"
Can anyone help me to resolve this issue? The other links on stack overflow are not of much help!
When I removed id uid field then Django is showing me:
You are trying to add a non-nullable field 'id' to registration without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
The issue is why I should provide a default value for id which django automatically creates?
UPDATE: I have deleted the migration folder, so I was resolve the above issue but now I am getting an error:
"Error creating new content types. Please make sure contenttypes "
RuntimeError: Error creating new content types. Please make sure
contenttypes is migrated before trying to migrate apps individually.
You should not have defined a default value for uid in the first place. It's an AutoField, it gets an auto-incremented value from the database.
I am new to programming Django, so I'm not sure if this is possible.
I have created a new CustomUser class:
class CustomUser(AbstractBaseUser):
email = models.EmailField(verbose_name='email address', max_length=255, unique=True)
mobile = models.CharField(max_length=30, null=True)
first_name = models.CharField(max_length=50, null=True)
middle_name = models.CharField(max_length=50, null=True)
last_name = models.CharField(max_length=50, null=True)
date_of_birth = models.DateField(null=True)
Primary_address = models.CharField(max_length=50, null=True)
Primary_address_zipcode = models.CharField(max_length=5, null=True)
is_active = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
A few questions:
Question 1: I have redefine some of the fields that exists in the default User class (e.g. First Name, Last name, Date Joined). However, I didn't define Last_login. But last_login still shows up as a column in the admin page. But if I don't define First Name, Last Name and Date Joined in my new CustomUser, I get an error and doesn't show up in the admin page. Why is last login special?
Question 2: The default admin page has great UI for group and permission control. Is it possible to define my CustomerUser and still use/enable the default admin page?
Thanks.
you dont need to define all these fields that are already there in django. dont reinvent the wheel. what error are you getting? traceback?
using your customuser model has nothing to do with using default admin page. you can always use django admin page no matter what models you have. Or i dont understand what you really want to achieve.