Error - django.db.migrations.exceptions.CircularDependencyError: accounts.0001_initial, songs.0001_initial
I have two apps accounts and songs. Songs have two model files - models.py and song_metadata_models.py
accounts/models.py
class AppUser(models.Model):
user = models.OneToOneField(User)
user_languages = models.ManyToManyField('songs.SongLang')
user_genres = models.ManyToManyField('songs.SongGenre')
def __str__(self):
return self.user.username
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
songs/song_metadata_models.py
class SongGenre(models.Model):
short_name = models.CharField(max_length=10)
full_name = models.CharField(max_length=100)
def __str__(self):
return self.full_name
class SongLang(models.Model):
short_name = models.CharField(max_length=10)
full_name = models.CharField(max_length=100)
def __str__(self):
return self.full_name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
songs/models.py
class Song(models.Model):
# Fields
name = CharField(max_length=255)
slug = AutoSlugField(populate_from='name', blank=True)
created = DateTimeField(auto_now_add=True, editable=False)
last_updated = DateTimeField(auto_now=True, editable=False)
url = CharField(max_length=100)
artist = CharField(max_length=50)
album = CharField(max_length=50)
like = BooleanField(default=False)
dislike = BooleanField(default=False)
# Relationship Fields
requested_by = ForeignKey('accounts.AppUser', related_name='song_requested_by')
dedicated_to = ManyToManyField('accounts.AppUser', null = True, blank = True,related_name='song_dedicated_to')
recommended_to = ManyToManyField('accounts.AppUser', null = True, blank = True,related_name='song_recommended_to')
How to solve this? There is no circular dependency at models level then why this issue?
Solution 1: move the AppUser's many2many to SongLang and SongGenre. A m2m relationship is by default symetric so you can declare it on either side of the relationship (nb: just make sure to set the related_name to how your fields was named in the AppUser model).
Solution 2: move your SongGenre and SongLang models to a third app (the canonical solution to circular dependencies)
Solution 3: eventually try to first create the AppUser model without the m2m fields, creates the initial migration, then add the m2m fields (not sure it will work though).
Related
models.py
i have create foreignkey in table paymentsDetails i have stripe payment method which is working when user login session is created and by using session value i get the primarykey of that user by using 'ORM' method and then assign this primary key of specific user into the paymentdetails models field named as user_account_id
but i am getting error that i cannot assign 1 to PaymentsDetail.User_account_id must be a instance of UserAccountModel
class UserAccountModel(models.Model):
ContactEmail = models.EmailField(max_length=30)
FirstName = models.CharField(max_length=30)
LastName = models.CharField(max_length=40)
Counrty = models.CharField(max_length=50)
Phone = models.IntegerField()
ChooseUserName = models.CharField(max_length=30)
password = models.CharField(max_length=32)
EnterCaptcha = models.CharField(max_length=4)
payments = models.BooleanField(max_length=6, default=False)
showsponsor = models.CharField(max_length=30, default=False)
RegisteredDate = models.DateTimeField(auto_now_add=True, blank=True)
ActivationOn = models.DateField(auto_now_add=False,blank=True)
expiry_date = models.DateField(auto_now_add=False,blank=True)
def __str__(self):
return self.FirstName + ":" + self.ChooseUserName
class PaymentsDetail(models.Model):
refrer_name = models.CharField(max_length=32,default="", editable=False)
sponser_name = models.CharField(max_length=32)
status = models.CharField(default='comped', max_length=32)
s_id = models.CharField(max_length=32)
registered = models.DateTimeField(auto_now_add=True)
activated_date = models.DateField(auto_now_add=False)
Due_Date = models.DateField(auto_now_add=False)
payment = models.CharField(default='$',max_length=32)
User_Account_id = models.ForeignKey(UserAccountModel, on_delete=models.CASCADE, default=True, editable=True)
addprogrameReference = models.ForeignKey(AddProgramModel, on_delete=models.CASCADE, default=True, editable=True)
class Meta:
ordering = ['User_Account_id', 'addprogrameReference']
def str(self):
return self.refrer_name + ":" + self.user_account
i am getting the error
cannot assign 1 to PaymentsDetail.User_account_id must be a instance
of UserAccountModel
views.py
print("user payment"+str(charge.amount))
pays = str(charge.amount)
user_id = random.randint(0, 999) # returns a random integer
user = User.objects.get(username=str(rerredby))
userKey = user.pk
print("this one is for user upper")
# saving record
payment_insertion = PaymentsDetail.objects.create(
User_Account_id=userKey,
refrer_name=rerredby,
sponser_name=rerredby,
s_id=str(user_id),
registered=datetime.now(),
activated_date=datetime.now(),
Due_Date=datetime.now(),
payment=str(pays + "$"),
)
payment_insertion.save()
Simply change this string:
payment_insertion = PaymentsDetail.objects.create(
User_Account_id=user,
...)
You are trying to assign int object where Django expects an instance.
Your view implementation is not right. The model class expects the field User_Account_id to be an instance of of UserAccountModel (since, your model definition User_Account_id = models.ForeignKey(UserAccountModel, on_delete=models.CASCADE, default=True, editable=True) told it to expect it regardless of the your field name ending with an id). therefore, retrieve the UserAccountModel instance from db first.
However, if you still want to pass the id to instead of an object change the following in your view.
User_Account_id_id=userKey
ForeingKey fields can be populated by id instead of the concerned model object. But you have to append _id at the end of the field name e.g.
#models.py
class Author(models.Model):
name = models.CharField(max_length=250)
class Book(models.Model):
name = models.CharField(max_length=250)
author = models.ForeignKeyField(Author, on_delete=models.CASCADE)
# views.py
def create_book(request):
name = request.POST.get('name', '')
author_id = request.POST.get('author_id', '')
Book.objects.create(name=name, author_id=author_id)
return HttpResponse(status=201)
Notice that there is no author_id field defined in the Book model. This field is implicitly defined by django ORM once you defined author field as a ForeignKey reference to Author model.
Using Django 1.8
I have an unmanaged model that points to a view in the db and I'm trying to return a queryset based on a derived field.
Here is a basic example of the model structure:
class Book(models.Model):
book_id = models.IntegerField()
publisher = models.CharField(max_length=20, null=True) # Can join to Publisher.publisher_name
sku = models.CharField(max_length=15, null=True) # Can join to Sku.sku
class Meta:
managed = False
db_table = 'vw_book'
class Sku(models.Model):
sku = models.CharField(max_length=15)
publisher = models.ForeignKey('myapp.Publisher')
class Publisher(models.Model):
publisher_name = models.CharField(max_lenth=20)
region = models.ForeignKey('myapp.Region')
class Region(models.Model):
region_name = models.CharField(max_length=20)
I'm looking for a way to return a queryset of Book based on the region, derived from the publisher as the preferred field and then the sku. It is possible for these fields in Book to refer to different region fields as the data is unlcean and has been derived from multiple sources. I can add a method to the Book model to derive the region, but trying to get a queryset from this is too slow.
class Book(models.Model):
publisher = models.CharField(max_length=20, null=True)
sku = models.CharField(max_length=15, null=True)
class Meta:
managed = False
db_table = 'vw_book'
def get_region(self):
if not self.publisher:
if not self.sku:
return ''
try:
sku = Sku.objects.get(sku=self.sku)
return sku.publisher.region.region_name
except Sku.DoesNotExist:
return ''
try:
publisher = Publisher.objects.get(publisher_name=self.publisher)
return publisher.region.region_name
except Publisher.DoesNotExist:
return ''
region_dict = {}
for book in Book.objects.all():
region_dict.setdefault(book.get_region(), []).append(book.book_id)
Book.objects.filter(book_id__in=region_dict.get('UK', []))
I am unable to add an extra field to the Book model. Is there a more efficient way I can do this?
I would filter the skus and then filter books based on the skus you receive
skus = Sku.objects.filter(publisher__region__region_name=region).values_list('sku', flat=True)
Book.objects.filter(sku__in=skus)
You can do the same with publishers if need be and do an Or query.
.filter(Q(publisher__in=publishers) |Q(sku__in=skus))
I've been reading similar questions to mine but they didn't help me.
I'm getting this error while I try to submit my form:
Cannot assign "9": "Characterweapons.weaponid" must be a "Weapons" instance.
This "9" is the ID from the weapon I got from my form, so that's very good, but when I try to put it in my weaponid column in my table Characterweapons, it gives me the error.
models.py:
from __future__ import unicode_literals
from django.db import models
class Category(models.Model):
categoryid = models.AutoField(db_column='CategoryID', primary_key=True) # Field name made lowercase.
categoryname = models.CharField(db_column='CategoryName', max_length=50, blank=True, null=True) # Field name made lowercase.
class Meta:
managed = True
db_table = 'category'
def __str__(self):
return self.categoryname
class Characters(models.Model):
characterid = models.AutoField(db_column='CharacterID', primary_key=True) # Field name made lowercase.
name = models.CharField(db_column='Name', unique=True, max_length=255) # Field name made lowercase.
level = models.IntegerField(db_column='Level') # Field name made lowercase.
credits = models.IntegerField(db_column='Credits') # Field name made lowercase.
class Meta:
managed = True
db_table = 'characters'
def __str__(self):
return '%s %s %s' % (self.name, self.level, self.credits)
class Weapons(models.Model):
weaponid = models.AutoField(db_column='WeaponID', primary_key=True) # Field name made lowercase.
weaponname = models.CharField(db_column='WeaponName', unique=True, max_length=255) # Field name made lowercase.
class Meta:
managed = True
db_table = 'weapons'
def __str__(self):
return '%s %r' % (self.weaponname, self.weaponid)
class Characterweapons(models.Model):
characterid = models.ForeignKey(Characters, models.DO_NOTHING, db_column='CharacterID') # Field name made lowercase.
weaponid = models.ForeignKey(Weapons, models.DO_NOTHING, db_column='WeaponID', blank=True, null=True) # Field name made lowercase.
categoryid = models.ForeignKey(Category, models.DO_NOTHING, db_column='CategoryID', blank=True, null=True) # Field name made lowercase.
quantity = models.IntegerField(db_column='Quantity', blank=True, null=True) # Field name made lowercase.
class Meta:
managed = True
db_table = 'characterweapons'
def __str__(self):
return '%s' % (self.quantity)
class DjangoMigrations(models.Model):
app = models.CharField(max_length=255)
name = models.CharField(max_length=255)
applied = models.DateTimeField()
class Meta:
managed = True
db_table = 'django_migrations'
I don't know if it is a FK problem, PK... no idea and I cannot find information to solve it...
views.py: (where the error has to be):
def submission(request):
print("Registered successfully")
Name = request.POST["Name"]
Level = request.POST["Level"]
Credits = request.POST["Credits"]
Mainhand = request.POST["Mainhand"]
Offhand = request.POST["Offhand"]
info = Characters(name=Name,level=Level,credits=Credits)
info.save()
mh=
infomh = Weapons.objects.values_list('weaponid',flat=True)
a=0;
for a in infomh:
if a == Mainhand:
a = Mainhand;
print("a: ")
print(a)
print("Mainhand")
print(Mainhand)
print("infmh:")
print(infomh)
charid = Characters.objects.latest('characterid')
info_mh = Characterweapons(characterid=charid,categoryid=1,weaponid=a)
info_mh.save()
#info_oh = Characterweapons(characterid=charid,weaponid=9,categoryid=2)
#info_oh.save()
return return_charnames(request)
With these prints I made sure that the values of my weaponsID are correct, they are.
I also wanna point out that the value=9 in the column "weaponid" exists in "Weapons" table.
Thanks all.
I think you better first fix your models. In Django a ForeignKey is conceptually a reference to an object to which you refer, not the id. Of course in the database it is stored as an id, but that is a layer that you should not care much about.
So I would advice to first rename the fields like weaponid to weapon:
class Characterweapons(models.Model):
character = models.ForeignKey(Characters, models.DO_NOTHING, db_column='CharacterID')
weapon = models.ForeignKey(Weapons, models.DO_NOTHING, db_column='WeaponID', blank=True, null=True)
category = models.ForeignKey(Category, models.DO_NOTHING, db_column='CategoryID', blank=True, null=True)
quantity = models.IntegerField(db_column='Quantity', blank=True, null=True)
# ...
Now if you construct a ForeignKey with the name fieldname, Django actually introduces two fields: the fieldname which is - like said before - a reference to a model object to which the ForeignKey refers, and a field fieldname_id that stores the id (the primary key) of that object. These two fields thus act like "twins".
We can then rewrite the submission view like:
def submission(request):
print("Registered successfully")
name = request.POST["Name"]
level = request.POST["Level"]
credits = request.POST["Credits"]
mainhand = request.POST["Mainhand"]
offhand = request.POST["Offhand"]
info = Characters.objects.create(name=name, level=level,credits=credits)
if Weapons.objects.filter(weapon_id=mainhand).exists():
a = mainhand
info_mh = Characterweapons.objects.create(
character_id=info.pk,
category_id=1,
weapon_id=a
)
return return_charnames(request)
In the above I did some refactorings as well:
In Python variables in functions typically have lowercase names;
you do not need to loop over weapon_ids, you can use an EXISTS query, which is typically faster;
Instead of first constructing a model instance, and then obj.save() it, you can use Model.objects.create(..) instead;
you probably do not want to fetch the latest(..) value, but use the pk of the info object instead, since that is the one we constructed, and furthermore if there is no order defined (like here), the order can be any order the database likes, not per se the latest one added.
You probably still need to rewrite hardcoded identifiers (like a=1, and category_id=1, since it is perfectly possible that those objects do not exist in the database).
Your foreignkey weaponid in the model Characterweapons is a Weapon instance not only its id.
From that id, query the object and assign it.
I have a polling app with one of the models "Choice" consisting of 2 Foreign key fields linked to the "Person" model.
I wanted to automatically populate related "photo_other" field (with the image link) once I have selected the "name" of the person. "name" is also a Foreign Key Field linked with Choice model.
models.py
class Choice(models.Model):
name = models.ForeignKey(Person)
photo_other = models.ForeignKey(Person)
rating = models.DateTimeField(blank=True, null=True)
def __unicode__(self):
return smart_unicode(self.name)
class Person(models.Model):
name = models.CharField(max_length=250)
photo = models.ImageField(upload_to="photos")
pub_date = models.DateTimeField()
def __unicode__(self):
return smart_unicode(self.name)
Why do you want to store the same value in two different tables when they are connected through a foreign key? It just doesn't make sense.
class Choice(models.Model):
name = models.ForeignKey(Person)
rating = models.DateTimeField(blank=True, null=True)
#property
def photo_other(self):
return self.name.photo
class Person(models.Model):
name = models.CharField(max_length=250)
photo = models.ImageField(upload_to="photos")
pub_date = models.DateTimeField()
In order to make photo_other visible under the admin page of Choice model, you can do the following;
class ChoiceAdmin(admin.ModelAdmin):
list_display = ['name', 'rating', 'get_photo']
def get_photo(self, obj):
return obj.photo_other
get_photo.short_description = 'Photo'
Django admin shows an empty field instead of "ajax select widget".
Tried on the other project - in models with two m2m relations to completely equal models with different names. Works like a charm on one field, shows empty place on other. Any help or links?
models.py
class Company(models.Model):
"""Companies - customers """
title = models.CharField('Nosaukums', blank=False, max_length=200)
is_costumer = models.BooleanField('Pasūtītājs', default=False)
is_subcontractor = models.BooleanField('Apakšuzņēmējs', default=False)
class Meta:
verbose_name = 'Uzņēmums'
verbose_name_plural = 'Uzņēmumi'
def __unicode__(self):
return self.title
class Project(models.Model):
"""Projects"""
number = models.IntegerField('Īsais numurs', blank=False, null=False)
title = models.CharField('Nosaukums', blank=False, max_length=250)
customers = models.ManyToManyField(Company, verbose_name='Pasūtītāji', blank=True, null=True)
is_active = models.BooleanField('Aktīvs', default=True)
notes = models.TextField('Piezīmes', blank=True)
class Meta:
verbose_name = 'Projekts'
verbose_name_plural = 'Projekti'
def costumer_list(self):
list = "pasūtītāji"
return list
def __unicode__(self):
return self.title
Based on the model you posted above and the image of the admin file, your filter_hoizontal variable should be filter_horizontal = ('customers',) instead of filter_horizontal = ('costumers',) In other words, the spelling of customers differs between your model and admin files.
Some of my m2m fields did not allow form_horizontal. I found that the only thing these specific fields had in common was that they were all for categories, in my native language this is categorieën, which happens to have an accent on the last e.
See my field definition below:
categories = models.ManyToManyField (
'FAQCategories',
verbose_name = 'Categorieën',
blank = True,
)
The problem here is that I did not tell python my string should be treated as Unicode. When I changed the verbose_name to u'Categoriën' it worked!
In retrospect this was very obvious to me but I hope this will help you or some else.. Define those strings properly, lesson learned!