I am new to Django and am creating a small Twitter app for practice. I have the following models set up
class Profile(models.Model):
#Relations
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
related_name="profile",
verbose_name=_("user"),
primary_key=True,
)
interaction = models.PositiveIntegerField(
default=0,
verbose_name=_("interaction")
)
# Object Manager
objects = managers.ProfileManager()
#Custom Properties
#property
def username(self):
return self.user.username
#Methods
#Meta and String
class Meta:
verbose_name = _("Profile")
verbose_name_plural = _("Profiles")
ordering = ("user",)
def __str__(self):
return self.user.username
#receiver(post_save,sender=settings.AUTH_USER_MODEL)
def create_profile_for_new_user(sender,created,instance,**kwargs):
if created:
profile = Profile(user=instance)
profile.save()
class Tweet(models.Model):
profile = models.ForeignKey(Profile,unique=False)
text = models.CharField(max_length=100,primary_key=True)
class Meta:
verbose_name = _("Tweet")
#ordering = ("profile","text")
def __str__(self):
return self.text
class Comment(models.Model):
profile = models.ForeignKey(Profile,unique = False,default=None)
tweet = models.ForeignKey(Tweet,unique=False)
text = models.CharField(max_length=100,primary_key=True)
def __str__(self):
return self.text
I would like the Comment Model to have to two Foreign keys: one to the User who posted it and one to the Tweet it is a comment of. Whenever I tried to run my app I get the following error:
column taskmanager_comment.profile_id does not exist
LINE 1: SELECT "taskmanager_comment"."profile_id", "taskmanager_comm...
I have done python manage.py makemigrations. In addition,I have added a default=None to the profile foreign key in Comment because Django throws an error for a Non-nullable field if I don't add it. python manage.py migrate throws the following error every time I run it:
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 221, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/db/migrations/executor.py", line 110, in migrate
self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/db/migrations/executor.py", line 147, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/db/migrations/migration.py", line 115, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/db/migrations/operations/fields.py", line 201, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
File "/home/lie/.virtualenvs/tb_dev/lib/python3.4/site-packages/django/db/backends/base/schema.py", line 467, in alter_field
old_field.rel.through._meta.auto_created and
AttributeError: 'str' object has no attribute '_meta'
which I am not sure if this error could be causing the previous error. Any ideas how to fix these errors?
Edit: Migrations:
python manage.py makemigrations
Migrations for 'taskmanager':
0001_initial.py:
- Create model Comment
- Create model MyModel
- Create model Profile
- Create model Tweet
- Add field profile to comment
- Add field tweet to comment
(tb_dev)lie#lie-bot:~/taskbuster_project$ python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: google, staticfiles, allauth, messages
Apply all migrations: sessions, account, taskmanager, socialaccount, contenttypes, admin, auth, sites
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
No migrations to apply.
Firstly, I would recommend removing the `primary_key=True' from your text fields. This makes them unique and indexed - meaning, no one will ever be able to tweet the same thing or comment the same thing. Also, primary keys are reserved for the id of that record, whether it is auto generated or generated by you.
Second, you do not need unique=False on your Foreign keys in the Comment model
Third, You do not need to associate the Comment model to the Profile model, since it is associated by the Tweet... Profile -> Tweet -> Comment
So:
class Profile(models.Model):
# a field of 'id' is automatically generated for you as the primary key
#Relations
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
verbose_name=_("user"),
)
interaction = models.PositiveIntegerField(
default=0,
verbose_name=_("interaction")
)
# Object Manager
objects = managers.ProfileManager()
#Custom Properties
#property
def username(self):
return self.user.username
#Methods
#Meta and String
class Meta:
verbose_name = _("Profile")
verbose_name_plural = _("Profiles")
ordering = ("user",)
def __str__(self):
return self.user.username
#receiver(post_save,sender=settings.AUTH_USER_MODEL)
def create_profile_for_new_user(sender,created,instance,**kwargs):
if created:
profile = Profile(user=instance)
profile.save()
class Tweet(models.Model):
# a field of 'id' is automatically generated for you as the primary key
profile = models.ForeignKey('Profile')
text = models.CharField(max_length=100)
class Meta:
verbose_name = _("Tweet")
#ordering = ("profile","text")
def __str__(self):
return self.text
class Comment(models.Model):
# a field of 'id' is automatically generated for you as the primary key
profile = models.ForeignKey('Profile')
tweet = models.ForeignKey('Tweet')
text = models.CharField(max_length=100)
def __str__(self):
return self.text
is probably more of what you had in mind
Profile has a ONE-TO-ONE relationship to the AUTH_USER model. A Profile can have MANY tweets and a Tweet can have MANY comments.
To select someone's tweets and comments by username, you could call:
tweets = Tweet.objects.filter(profile__user__username='incognos').select_related('comments')
or by user record in a view:
tweets = Tweet.objects.filter(profile__user=request.user).select_related('comments')
This gets all the tweets by the user named 'incognos' and in the same query, selects all the related comments to that tweet.
I hope this helps and welcome to Python and Django....
Related
I am working on a commerce app, (with django but very new to it) where a user can create a listing through a ModelForm called ListingForm that inherits from a Model called Listing.Here is the code for the the Listing model and ListingForm:
from django.contrib.auth.models import AbstractUser
from django.db import models
class Listing(models.Model):
NAME_CHOICES = [
('Fashion', 'Fashion'),
('Toys','Toys'),
('Electronic','Electronics'),
('Home', 'Home'),
('Other', 'Other')
]
import datetime
title = models.CharField(max_length= 64)
date_made = models.DateField(default= datetime.date.today())
description = models.TextField()
user = models.ForeignKey(User, to_field='username', on_delete=models.CASCADE, related_name='user_listings', null=True)
starting_bid = models.DecimalField(decimal_places=2, max_digits=264, default=10.00)
image_url = models.CharField(blank=True, max_length=1000)
category = models.ForeignKey(Category, on_delete=models.CASCADE, to_field='name', related_name='category_listings', default=NAME_CHOICES[4][0])
listing_category = models.CharField(max_length=12, choices=NAME_CHOICES, null=True, default=NAME_CHOICES[4][0])
is_active = models.BooleanField(default=True)
def __str__(self):
return f'{self.title}'
Here is the code for the ```ListingForm``:
from .models import Listing
from django.forms import ModelForm
class ListingForm(ModelForm):
class Meta:
model = Listing
exclude = [
'date_made',
'user',
'category',
'is_active',
]
The Listingmodel also has foreignkeys to and within the models User,Category and Bid.
Here is the code for these models(same imports as those shown for Listing model):
class User(AbstractUser):
def __str__(self):
return f'{self.username} '
class Category(models.Model):
NAME_CHOICES = [
('Fashion', 'Fashion'),
('Toys','Toys'),
('Electronic','Electronics'),
('Home', 'Home'),
('Other', 'Other')
]
name = models.CharField(max_length=12, choices= NAME_CHOICES, unique=True)
def __str__(self):
return self.name
class Bid(models.Model):
value = models.DecimalField(decimal_places=2, max_digits=256)
listing = models.ForeignKey('Listing', on_delete=models.CASCADE, related_name='bid_listings', default=20.00)
def __str__(self):
return f'{self.value}'
I want the user to be able to create a listing through a function based view:
def create_listing(request):
if request.method == 'POST':
import datetime
listing_form = ListingForm(request.POST)
bid = request.POST['starting_bid']
if listing_form.is_valid():
listing_form.save(commit=False)
listing_form.user = request.user
listing_form.date_made = datetime.datetime.today()
listing_form.is_active = True
listing_form.save()
Bid.objects.create(value=bid, listing=listing_form)
return HttpResponse('Listing has been saved successfully!')
else:
listing_form = ListingForm()
return render(request, 'auctions/createlisting.html',{
'listing_form':listing_form
})
Upon attempting to run py manage.py runserver in the terminal, I get an Integrity error at /createlisting.
This is the traceback:
Traceback (most recent call last):
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\ACER\Desktop\Projects\commerce\auctions\views.py", line 84, in create_listing
listing_form.save()
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\models.py", line 548, in save
self.instance.save()
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\base.py", line 806, in save
self.save_base(
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\base.py", line 857, in save_base
updated = self._save_table(
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\base.py", line 1000, in _save_table
results = self._do_insert(
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\base.py", line 1041, in _do_insert
return manager._insert(
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\query.py", line 1434, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\sql\compiler.py", line 1632, in execute_sql
self.connection.ops.fetch_returned_insert_columns(
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\backends\base\operations.py", line 205, in fetch_returned_insert_columns
return cursor.fetchone()
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\utils.py", line 97, in inner
with self:
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\ACER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\utils.py", line 98, in inner
return func(*args, **kwargs)
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
[10/May/2022 21:00:05] ←[35;1m"POST /createlisting HTTP/1.1" 500 135972←[0m
How do I resolve this error? I suspect it has something to do with the uniqueness of my ids in one of my models, or the lack thereof.
First, in your models.py, you can change the date_made from DateField to a DateTimeField so you can save the time that your listing have been created on without need to import the datetime library and to override iton your views when the form is submitted by adding an attribute which is the auto_now_add:
...
date_made = models.DateTimeField(auto_now_add=True)
this article might be helpful if you wanna look for the difference between The DateTimeField and the DateField
https://www.jafoor.com/post/django-datetimefield-datefield/
Secondly, in your views.py, you can simply grab your grid coming from post data in your form by using the cleaned_data method that comes with our form, and from it we can grab all the post data coming, and it would be more better if you put this inside the if listing_form.is_valid():
...
if listing_form.is_valid():
bid = listing_form.cleaned_data['starting_bid']
Read more about cleaned_data method here:
What is the use of cleaned_data in Django
Thirdly, in your views.py, you gotta change the listing attribute in the Bid.objects.create() from listing_form to listing_form.instance, the instance here means the object that your form is posting instead of assigning the whole form and ofc it'll get you an error:
...
Bid.objects.create(value=bid, listing=listing_form.instance)
Now let's talk about your problem.
To solve it first you gotta assign an attribute to your category field in the Listing class in your models.py which is db_constraint and we'll set it to False:
...
category = models.ForeignKey(Category, on_delete=models.CASCADE, to_field='name', related_name='category_listings', default=NAME_CHOICES[4][0], db_constraint=False)
then in your cmd type python manage.py makemigrations then python manage.py migrate to migrate this change in your database
Then, go and register your Category model in admin.py so you can create categories manually from the Admin panel to assign later in your form:
from .models import Category
admin.site.register(Category)
Then go and make your categories from your admin panel.
Last but not least go to your views.py, and we'll add the category of your Listing manually by grabbing the listing_category field from our form by the cleaned_data function and by this we will grab the category that have the same name as the listing_category:
from .models import Listing, Bid, Category
...
if listing_form.is_valid():
...
listing_form.category = Category.objects.get(name=listing_form.cleaned_data['listing_category'])
...
If you got any other issue contact me on my discord: Ramy#8162
(New to Django) - I am looking to create two model with a foreign key. The first model is called Portfolio, and each Portfolio has many member through the second model Portfoliomember.
It currently looks like this:
class Portfolio(models.Model):
portfolio_name = models.CharField(max_length=30, blank=True, null=True)
def __str__(self):
return self.portfolio_name
class Meta:
db_table = "portfolio"
class PortfolioMember(models.Model):
portfolio = models.ForeignKey(Portfolio, related_name = "portfoliomember", on_delete=models.CASCADE)
quality = models.FloatField(blank=True, null=True)
def __str__(self):
return self.portfolio
class Meta:
db_table = "portfoliomember"
Later i aim at using formset in a form. but for now, when i try to create the migration, i get the following :
Running migrations:
Applying app.0019_auto_20210318_1544...Traceback (most recent call last):
File "C:\Users\FrankyDoul\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedTable: relation "portfoliomember" does not exist
django.db.utils.ProgrammingError: relation "portfoliomember" does not exist
Is there an obvious reason why this would not work ?
Why do you define in your Meta class db_table? I don't know what is your app name but normally you don't need to do that except for specific reason. See this (https://docs.djangoproject.com/en/3.1/ref/models/options/) " Django automatically derives the name of the database table from the name of your model class and the app that contains it".
So when you define db_table = 'another_name', you override the database table name. I would suggest to remove this line i.e. db_table = "portfoliomember" and see if the error persist.
I am using Django 1.11 and typed below codes in models.py. It works fine when makemigrations, but it notices the error of "models.DoesNotExist" when do migrate.
The code in models.py:
class RecordType(models.Model):
name = models.CharField(max_length=100, default='out',blank=True, verbose_name="name")
def get_record_type_default():
return RecordType.objects.get_or_create(pk=1)[0].id
class PrimaryCategory(models.Model):
type = models.ForeignKey(RecordType, on_delete=models.PROTECT, default=get_record_type_default, verbose_name="type")
def get_primary_category_default():
return PrimaryCategory.objects.get_or_create(pk=1)[0].id
class SecondaryCategory(models.Model):
primary_category = models.ForeignKey(PrimaryCategory, on_delete=models.PROTECT, default=get_primary_category_default, verbose_name="1st category")
def get_secondary_category_default():
return SecondaryCategory.objects.get_or_create(pk=1)[0].id
class Record(models.Model):
secondary_category = models.ForeignKey(SecondaryCategory, on_delete=models.PROTECT, default=get_secondary_category_default, verbose_name="2nd category")
And here is the error message while doing migrate:
File "C:\Users\myname\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\query.py", line 464, in get_or_create
return self.get(**lookup), False
File "C:\Users\myname\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\query.py", line 380, in get
self.model._meta.object_name
datacore.models.DoesNotExist: SecondaryCategory matching query does not exist.
you can use following way to create object:
get_object_or_404(RecordType, pk=id)
I know there are questions in SO regarding this issue. But most questions relates to AbstractBaseUser. I did not find any question with AbstractUser.
PROBLEM:
I want to implement authentication for django project. So I thought of implementing custom user model by inheriting AbstractUser.
Here is my Model:
class User(AbstractUser):
phonenumber = models.CharField(max_length=25,unique=True)
username = models.CharField(max_length=25,default="")
profile_path = models.URLField(max_length=1500)
country = models.CharField(max_length=100,default="")
what_do_you_do = models.CharField(max_length=500,default="")
where_do_you_do = models.CharField(max_length=500,default="")
time_stamp = models.DateTimeField(auto_now_add=True,blank=True)
USERNAME_FIELD = 'phonenumber'
I have added AUTH_USER_MODEL = 'XXX.User' in settings.py . And I thought of creating a super user.
python manage.py createsuperuser
But it is giving me following error:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/base.py", line 294, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 63, in execute
return super(Command, self).execute(*args, **options)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/base.py", line 345, in execute
output = self.handle(*args, **options)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 183, in handle
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
TypeError: create_superuser() takes exactly 4 arguments (3 given)
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyUserManager(BaseUserManager):
def create_user(self, phonenumber, password=None):
if not phonenumber:
raise ValueError('Users must have an phonenumber')
user = self.model(
phonenumber=phonenumber,
)
user.save(using=self._db)
return user
def create_superuser(self, phonenumber, password=None):
user = self.model(
phonenumber=phonenumber
)
user.is_admin = True
print(password)
user.set_password(password)
user.save(using=self._db)
return user
class User(AbstractBaseUser):
phonenumber = models.CharField(max_length=25,unique=True)
user= models.CharField(max_length=25,default="")
profile_path = models.URLField(max_length=1500)
country = models.CharField(max_length=100,default="")
what_do_you_do = models.CharField(max_length=500,default="")
where_do_you_do = models.CharField(max_length=500,default="")
time_stamp = models.DateTimeField(auto_now_add=True,blank=True)
is_admin = models.BooleanField(default=False)
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return self.is_admin
objects = MyUserManager()
USERNAME_FIELD = 'phonenumber'
#property
def is_staff(self):
return self.is_admin
def get_short_name():
return self.phonenumber
According to Django docs:
You should also define a custom manager for your User model. If your User model defines username, email, is_staff, is_active, is_superuser, last_login, and date_joined fields the same as Django’s default User, you can just install Django’s UserManager; however, if your User model defines different fields, you will need to define a custom manager that extends BaseUserManager providing two additional methods:create_user() and create_superuser()
As such, I have provided you a custom manager. Keep your settings as per normal. Note: As shown in your model, you have no password field so I assumed you did not need one in this case.
Also extend from AbstractBaseUser, not AbstractUser.
The problem is in user model created by you.
class User(AbstractUser):
phonenumber = models.CharField(max_length=25,unique=True)
username = models.CharField(max_length=25,default="")
profile_path = models.URLField(max_length=1500)
country = models.CharField(max_length=100,default="")
what_do_you_do = models.CharField(max_length=500,default="")
where_do_you_do = models.CharField(max_length=500,default="")
time_stamp = models.DateTimeField(auto_now_add=True,blank=True)
REQUIRED_FIELDS = ['username']
Add REQUIRED_FIELDS in your model.
One More thing,AbstractUser should be used if you like Django’s User model fields the way they are, but need extra fields.So it means,If you want to use AbstractUser,then you should add new fields in the user Model and not rewrite the predefined fields of Django auth user model. So you need to remove all the fields already inside Django User model or Use AbstractBaseUser for entirely new User Model.
Read further from Here.
You can implementing custom usermodel like this way-:
from django.contrib.auth.models import AbstractBaseUser, UserManager
from django.contrib.auth.models import PermissionsMixin
class User(AbstractBaseUser, PermissionsMixin):
'''
'''
username = models.CharField(max_length=50, null=True)
first_name =models.CharField(max_length=50, null=True)
last_name = models.CharField(max_length=50, null=True)
email = models.EmailField(unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', ]
objects = UserManager()
I'm build models in Django 1.8, and I'm using abstract inheritance (which I'm assuming is contributing to the problem). I have abstract models and then I have models which are based on those abstract models. I also have ForeignKey and ManyToMany relations between some models.
Everything looks fine, but when I try to syncdb or 'makemigrations blog' I get an AttributeError which says 'NoneType' object has no attribute 'unique'.
I don't know why I'm getting it, and I tried experimenting with different model setups, and I read lots of forum posts, but for now I've hit a wall.
I'll post the traceback and my models below:
MODELS:
indie_db
from django.db import models
class URL(models.Model):
link = models.CharField(max_length=400)
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Artist(models.Model):
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
link = models.ForeignKey(URL)
class Meta:
abstract = True
ordering = ['name']
def __str__(self):
return self.name
class ArtistSingle(Artist):
birthdate = models.DateField(null=True, blank=True)
deathdate = models.DateField(null=True, blank=True)
class ArtistGroup(Artist):
members = models.ManyToManyField(ArtistSingle)
established = models.DateField(null=True, blank=True)
disbanded = models.DateField(null=True, blank=True)
class Contributor(models.Model):
contributing_artist = models.ForeignKey(ArtistSingle, null=True, blank=True)
alternate_name = models.CharField(max_length=200)
role = models.CharField(max_length=200)
class ProductionCompany(models.Model):
name = models.CharField(max_length=200)
link = models.ForeignKey(URL)
def __str__(self):
return self.name
class Work(models.Model):
title = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
created = models.DateField()
city = models.CharField(max_length=200)
production_company = models.ForeignKey(ProductionCompany, blank=True, null=True)
self_published = models.BooleanField(default=False)
creator = models.ForeignKey(Artist)
link = models.ForeignKey(URL)
styles = models.CharField(max_length=200)
contributors = models.ManyToManyField(Contributor)
class Meta:
abstract = True
ordering = ['-created']
def __str__(self):
return self.title
class MusicalWork(Work):
audio_links = models.ManyToManyField(URL)
class WrittenWork(Work):
excerpt = models.TextField(null=True, blank=True)
class PerformanceWork(Work):
venue = models.CharField(max_length=200)
class VideoWork(Work):
length = models.CharField(max_length=16)
class VisualWork(Work):
images = models.ManyToManyField(URL)
blog:
from django.db import models
# Create your models here.
class Tag(models.Model):
tag_name = models.CharField(max_length=200)
def __str__(self):
return self.tag_name
class Entry(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
slug = models.SlugField(max_length=200)
publish = models.BooleanField(default=True)
created = models.DateTimeField(auto_now=True)
modified = models.DateTimeField(auto_now=True)
tags = models.ManyToManyField(Tag)
def __str__(self):
return self.title
class Meta:
verbose_name = "Blog Entry"
verbose_name_plural = "Blog Entries"
ordering = ["-created"]
TRACEBACK:
[pattmayne#web476 weird_canada]$ python3.4 manage.py makemigrations blog
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/base.py", line 440, in execute
self.check()
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/management/base.py", line 478, in check
include_deployment_checks=include_deployment_checks,
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/checks/registry.py", line 72, in run_checks
new_errors = check(app_configs=app_configs)
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/core/checks/model_checks.py", line 28, in check_all_models
errors.extend(model.check(**kwargs))
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/base.py", line 1181, in check
errors.extend(cls._check_fields(**kwargs))
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/base.py", line 1258, in _check_fields
errors.extend(field.check(**kwargs))
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/fields/related.py", line 1829, in check
errors = super(ForeignKey, self).check(**kwargs)
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/fields/related.py", line 1502, in check
errors.extend(self._check_unique_target())
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/fields/related.py", line 1522, in _check_unique_target
for rel_field in self.foreign_related_fields)
File "/home/pattmayne/webapps/limbs_008/lib/python3.4/Django-1.8.2-py3.4.egg/django/db/models/fields/related.py", line 1522, in <genexpr>
for rel_field in self.foreign_related_fields)
AttributeError: 'NoneType' object has no attribute 'unique'
IF this is caused by my inherited models, what is the exact cause, and how should I change things?
Thanks in advance.
I believe the issue is actually with the Work models.
You have a ForeignKey to URL in the abstract class,
link = models.ForeignKey(URL)
And you also have keys to URL in some of the derived classes, for example MusicalWork:
class MusicalWork(Work):
audio_links = models.ManyToManyField(URL)
So MusicalWork has two links to URL. Which would be fine, except Django attempts to create a reverse relationship for URL to your model, usually called musicalwork_set for this case, but it has two reverse relationships for the same model!
The answer would be to specify a related_name field for any models that derive from it with the same model references.
Therefore:
class MusicalWork(Work):
audio_links = models.ManyToManyField(URL, related_name='musicalwork_audio_set')
But there may be other issues as that error message doesn't exactly point to this condition (trust me, Django has a much nicer error message for this particular mistake).
This is because you have a Foreign key to an Abstract Model.
creator = models.ForeignKey(Artist)
You can change this to ArtistSingle
creator = models.ForeignKey(ArtistSingle)
Ideally it should have thrown a proper error like
Field defines a relation with model 'Artist', which is either not installed, or is abstract.
But the crash is a bug with Django 1.8