Using model inheritance and encounting by non-nullable field error - python

I used inheritance model in my project after changing the model; but I give non-nullable field error. What should I do?
I am using Django 1.7
class Questions(models.Model):
question_category = models.ForeignKey(Course, blank=False)
question_author = models.ForeignKey(Author, blank=False)
question_details = models.CharField(max_length=100, blank=False, default='')
timestamp = models.DateTimeField(auto_now_add=True)
class TypeFive(Questions):
question_title = models.CharField(max_length=100, blank=False, default=generator(5), unique=True, editable=False)
def __str__(self):
return "{}".format(self.question_title)
class TypeFiveChoice(models.Model):
question_choice = models.ForeignKey(TypeFive)
is_it_question = models.BooleanField(default=False)
word = models.CharField(default='', blank=False, max_length=20)
translate = models.CharField(default='', blank=False, max_length=20)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "{} : {}, {}".format(self.question_choice, self.word, self.translate)
After migrations:
You are trying to add a non-nullable field 'questions_ptr' to typefive 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

In order to inherit from Questions in TypeFive, Django needs to add a relation from TypeFive to Questions. For all records in TypeFive that might already be in the database.
Django now doesn't know which question it should relate TopFive to. This is what the migrate command asks you for. You have a few options, but they greatly depend on your use case and whether you are in early development or if there is a production database where this migration has to run later.
I'm in early development and running it on localhost, so iI don't care
about my records. Now, what should I do?
In this case you haven't much to worry about, when migrate asks you type 1 and then press enter. Now add a primary key of a Questions instance that is in your database and then hit enter again.
Django now relates all TypeFive instances that are currently in the database to this question, so you might have to clean that up afterwards (e.g. by editing the TypeFive in Django admin).

#Nick Brady pointed this out in the question above so I don't mean to take credit but I wanted to highlight.
If your new inheritance class is only used for the purpose of being inherited from, you can easily get around this by setting your parent class to abstract.
class Parent(models.model):
Name = models.CharField(max_length=50)
class Meta:
abstract = True
class Child(Parent):
foobar = models.CharField(max_length=50)
class Meta:
db_table = "typenex_taxonomy_nodes"

Related

Django ManyToMany alternative pros and cons

I was developing a chat system with channels and have this models for a thread (some attributes removed for simplicity's sake):
class Thread(models.Model):
name = models.CharField(max_length=50, null=True, blank=True)
users = models.ManyToManyField('auth.User')
I realized it is also possible to implement it like this:
class Thread(models.Model):
name = models.CharField(max_length=50, null=True, blank=True)
class ThreadUsers(models.Model):
thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
What are the advantages/disadvantages of using one over the other?
All what you do - is the same. For your last example with custom M2M through model you can add M2M declaration users in Thread:
class Thread(models.Model):
name = models.CharField(max_length=50, null=True, blank=True)
# M2M declaration, which use your ThreadUsers
users = models.ManyToManyField('auth.User', through='ThreadUsers' )
class ThreadUsers(models.Model):
thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
Pros:
You create model self
you can change behavior your M2M connection manually.
You can add additional fields in M2M through connection.
You have full control of this model.
Cons:
problem with m2m connections in django admin.
too much additional code, you can get a hard-to-find errors.
some fields/widgets don't want to work with M2M.through.
all was happened is your problem, this is not tested. Auto-through relation is tested in box.
we have in our projects 50/50 M2M-autothrough vs M2M-manualthrough. if I want to have more control on the models and realations - i use custom through.
p.s. in M2M-autothrough case Django created SomethingLikeYourThreadUsers Model and Table automatically.

Delete 2 model different objects which reference each other as foreign keys

We have two Django models:
class Project(models.Model):
project_title = models.CharField(max_length=30)
owner = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING)
class User(models.Model):
usernmae = models.CharField(max_length=50)
active_project = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING, related_name='current_project')
I have a user with object (with id say 692). And this user created a project with id=12345, therefore these owner field will get have this particular referenced.
I want to delete that user. But it shows error that
delete on table "app_user" violates foreign key constraint
This is expected as on_delete=models.DO_NOTHING, was set. One way I found out was using on_delete=models.CASCADE.
Question: How should I go about deleting the user (692) without changing the model definition(having to re-run migration)?
Doing it manually by deleting the project first, leads to the same foreign-key error, as owner field is User object.
How to handle this mutual foreign key relationship while deleting, as deleting any one of those two throws the foreign-key exception?
Update
Some correction in the model definition username is the field name instead of usernmae (typo). And the foreignkey for project is Project not the User model.
class Project(models.Model):
project_title = models.CharField(max_length=30)
owner = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING)
class User(models.Model):
username = models.CharField(max_length=50)
active_project = models.ForeignKey(Project, null=True, on_delete=models.DO_NOTHING, related_name='current_project')
IF you really don't want to make a migration (any specific reason?) and if you are ok with doing this manually this time. Then you have two options:
Go into the admin panel and manually change the User field in the project instance to a different user or to NULL. Now you should be able to delete the User instance since it's not referred anymore into the project.
If that worked, you can then delete the project instane as well.
Curios if this will work, let me know!

django query compare two models

I have three models, I want to display users who apply for leave but I don't know how to accomplish that. The relationship between user to new leave is one to many and the leave balance to new leave is many to many and user to balance is one to one. I only want to display data from user and new leave.
class newleave(models.Model):
user=models.ForeignKey(User,default='',on_delete=models.CASCADE)
leave_balance=models.ManyToManyField(Leave_Balance)
leave=(
('annual','annual'),
('sick','sick'),
)
Leave_type=models.CharField(max_length=100,choices=leave,blank=False,default='')
dp=(
('test','test'),
('test1','test1'),
)
department=models.CharField(max_length=100,choices=dp,blank=False,default='')
Start_Date=models.DateField(null=True, blank=False, default=None)
End_Date=models.DateField(null=True, blank=False, default=None)
Total_working_days=models.FloatField(null=True, blank=False, default=None)
def __unicode__(self):
return self.Leave_type
class Leave_Balance(models.Model):
user=models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True,)
Outstanding_balance=models.FloatField(null=True, blank=True, default=None)
Monthly_entitlement=models.FloatField(null=True, blank=True, default=None)
Monthly_consumption=models.FloatField(null=True, blank=True, default=None)
Leave_current_balance= models.FloatField(null=True, blank=True, default=None)
Month=models.CharField(max_length=100,default="",null=True)
Year=models.CharField(max_length=100,default='')
def __unicode__(self):
return self.Year
The simple way to get users that have an entry in the newleave table is
User.objects.filter(newleave_set__isnull=False).distinct()
I would suggest following PEP8 for your code style as it allows programmers familiar with Python to quickly pick up the intentions of the programs that you write.
Class names should use the CapsWord convention - class NewLeave class LeaveBalance
Method names and instance variables should be lowercase words seperated by underscores NewLeave.start_date etc
The solution was quite straight forward but it took me a while to figure it out. I access the User models data via foreign key and Django actually took care of the joins.
views.py
def Allleaves(request):
allleave=NewLeave.objects.all()
return render(request,'allleave.html',locals())
and in the allleave.html, i access the the User info through the foreign key "user"
{% for leave in allleave%}
{{leave.user.first_name}}
{{leave.user.last_name}}
{{leave.Leave_type}}
{{leave.department}}
{%endfor%}

What field Django used in FOO_set?

I am little bit comfused. Lets say I have such models.
models.py:
class Company(models.Model):
name = models.CharField(blank=False, null=False)
class Game(models.Model):
developer = models.ForeignKey(Company, on_delete=models.CASCADE)
publishers = models.ManyToManyField(Company)
If I use next code:
current_company = Company.object.get(pk=1)
current_company.game_set.all()
as I understand it return all games of current_company, but what field (developer or publishers) Django used?
But this code wouldn't be valid, for precisely this reason. If you tried to run it, Django would tell you that there was a conflict in the reverse relation.
If you have two relationships pointing to the same model, you need to explicitly set related_name on one of them to avoid this conflict.

Django reference a Model by foreign key or a different field

I am using Django REST Framework. I have two models, Sites and Statuses.
class Sites(models.Model):
site_id = models.AutoField(primary_key=True)
status = models.ForeignKey(Statuses, models.DO_NOTHING, blank=True, null=True)
class Statuses(models.Model):
status_id = models.AutoField(primary_key=True)
description = models.CharField(max_length=255, blank=True, null=True, unique=True)
class Meta:
managed = True
db_table = 'Statuses'
I would like to be able to perform a GET on sites, and have the Statuses.description field returned (instead of Statuses.status_id). Also, I would like it so that either status_id or description may be used interchangeably in a POST to create a new site. Where does this type of functionality belong (serializer, models, etc...)?
I know I can accomplish the first part of my question by adding a property to the Sites model and then referencing this field in the Sites serializer.
#property
def status(self):
return self.row_status.description
However I thought the convention of a Model is that it should be a 1:1 representation of the database table. Is there a better way to do this?
This fits well in the serializer, like this:
class SitesSerializer(serializers.ModelSerializer):
description = serializers.CharField(source='status.description')
class Meta:
model = Sites
fields = ('site_id', 'description')
(But the status field should probably not have null=True set.)

Categories