Add a field to Mezzanine blogpost - django

I am using Mezzanine for a project. I need to add a extra field to Mezzanine blogpost.
I notice using EXTRA_MODEL_FIELDS can do it, but it looks complex.
I also try copy the blog folder from the site-package to my project path, and then modify the models.py. but I doesn't work.
I am new to Django, can some one help?
Thanks

By do some research, now I got the answer:
1. copy the blog app from sites-package to my project
2. change my setting.py
INSTALLED_APPS = (
"blog", #it was "mezzanine.blog",
.....
3. modify the blog/models.py
add following line to class BlogPost
shop_url= models.CharField(max_length=250,null=True, blank=True)
4. migirate the table (installed South)
./manage.py schemamigration blog --auto
./manage.py migrate blog

You can create a django app (CustomBlog), add it to your installed apps
and remove or comment the Mezzanine blog:
INSTALLED_APPS = (
"CustomBlog", #it was "mezzanine.blog",
...
)
In the models.py and admin.py, of your CustomBlog, inherit from the class BlogPost of Mezzanine:
models.py
from django.db import models
from mezzanine.blog.models import BlogPost
from mezzanine.blog.models import BlogCategory
class CustomBlog(BlogPost):
# Add New Field
# example
new_field = models.CharField(max_length=255)
class CustomBlogCategory(BlogCategory):
pass
admin.py
from django.contrib import admin
from .models import CustomBlog,CustomBlogCategory
admin.site.register(CustomBlog)
admin.site.register(CustomBlogCategory)
Then in the terminal create and run migrations
python manage.py makemigrations
python manage.py migrate

Related

Migrating models of dependencies when changing DEFAULT_AUTO_FIELD

I'm using Django 3.2. I've changed added this line to settings.py:
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
I then ran these commands:
$ python manage.py makemigrations
$ python manage.py migrate
The makemigrations command creates new migration files for my apps, not just the apps that I have created, but also in my dependencies. For example, I'm using django-allauth, and this file was created in my virtual environment (virtualenv):
.venv/lib/python3.8/site-packages/allauth/account/migrations/0003_auto_20210408_1526.py
This file is not shipped with django-allauth. When I deploy this application from git, this file is not included.
What should I do instead? How can I switch DEFAULT_AUTO_FIELD without the need to create new migration files for dependencies like django-allauth?
Ideally, your third party dependencies would include this line in the config found in apps.py:
from django.apps import AppConfig
class ExampleConfig(AppConfig):
default_auto_field = 'django.db.models.AutoField'
While waiting for upstream dependencies to update their apps.py or migration files, you can override the app config yourself. If it doesn't exist already, create an apps.py file in your main app directory (eg: project/apps.py), and override the config of a dependency. In this example, I'm overriding the config of django-allauth:
from allauth.account.apps import AccountConfig
from allauth.socialaccount.apps import SocialAccountConfig
class ModifiedAccountConfig(AccountConfig):
default_auto_field = 'django.db.models.AutoField'
class ModifiedSocialAccountConfig(SocialAccountConfig):
default_auto_field = 'django.db.models.AutoField'
Then modify INSTALLED_APPS in settings.py to look like this, replacing the old entries for django-allauth in this example:
INSTALLED_APPS = [
# ....
# replace: "allauth.account", with
"projectname.apps.ModifiedAccountConfig",
# replace: "allauth.socialaccount", with
"projectname.apps.ModifiedSocialAccountConfig",
]
If the dependency doesn't have an apps.py file to override, you can still create an AppConfig sub-class in project/apps.py like this:
from django.apps import AppConfig
class ModifiedExampleDependencyConfig(AppConfig):
name = 'exampledependency' # the python module
default_auto_field = 'django.db.models.AutoField'
Now when you run python manage.py makemigrations, no migration files should be created for the dependencies.
I work on a big project, we upgraded Django from 2.2. to 3.2 and then have got a need to create all new models with Big Integer (Int8) (PostgreSQL) field instead of default Integer (Int4).
When I defined it in settings.py:
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
I got the same problem, but with own apps - Django tried to make me to migrate 135 models I had, but I didn't want to do it. I only wanted to create new models with BigInt and manipuate olds manually.
I found the next solution. I changed the field to custom:
DEFAULT_AUTO_FIELD = 'project.db.models.CustomBigAutoField'
And then overrided its deconstruction:
from django.db import models
class CustomBigAutoField(models.BigAutoField):
"""Int8 field that is applied only for new models."""
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
if getattr(self, 'model', None):
path = 'django.db.models.AutoField'
return name, path, args, kwargs
As I discovered, fields of new models don't have a back reference to their models, so path wouldn't be overridden for them.
We override path because Django checks whether a model is changed by a key, that includes the path to this field. So we deceive Django and it thinks that existing model didn't changed.
I might not see the whole picture, but I tested it with different existing and new models and it worked for me. If someone tells me why this solution is bad, I'd be grateful.

Can't create Django superuser [duplicate]

I am trying to use Django's default Auth to handle register and log in.
setting.py:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'books',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
AUTH_USER_MODEL = 'books.User'
books.models.py:
class User(AbstractUser):
account_balance = models.DecimalField(max_digits=5, decimal_places=2, default=0)
views.py:
from django.contrib.auth.forms import UserCreationForm
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect("/accounts/profile/")
else:
form = UserCreationForm()
return render(request, "registration/register.html", {'form': form,})
urls.py:
urlpatterns = patterns('',
(r'^accounts/login/$', login),
(r'^accounts/logout/$', logout),
(r'^accounts/profile/$', profile),
(r'^accounts/register/$', register),
)
I tried deleting the db.sqlite3 file and re-ran python manage.py syncdb but I still get this error message:
OperationalError at /accounts/register/
no such table: auth_user
Request Method: POST
Request URL: http://127.0.0.1:8000/accounts/register/
Django Version: 1.7b4
Exception Type: OperationalError
Exception Value:
no such table: auth_user
./manage.py migrate
If you've just enabled all the middlewares etc this will run each migration and add the missing tables.
Only thing you need to do is :
python manage.py migrate
and after that:
python manage.py createsuperuser
after that you can select username and password.
here is the sample output:
Username (leave blank to use 'hp'): admin
Email address: xyz#gmail.com
Password:
Password (again):
Superuser created successfully.
Update
You are probably getting this error because you are using UserCreationForm modelform, in which in META it contains User(django.contrib.auth.models > User) as model.
class Meta:
model = User
fields = ("username",)
And here you are using your own custom auth model, so tables related to User has not been created. So here you have to use your own custom modelform. where in Meta class, model should be your User(books.User) model
This will work for django version <1.7:
Initialize the tables with the command
manage.py syncdb
This allows you to nominate a "super user" as well as initializing any tables.
it is need to make migration before create superuser.
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
Username : admin
Password : 12345678
python manage.py runserver
Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
try running
python manage.py migrate
then run
python manage.py createsuperuser
For custom forms( if you have made your own forms) use this command to migrate
python manage.py migrate --run-syncdb
If using a custom auth model, in your UserCreationForm subclass, you'll have to override both the metaclass and clean_username method as it references a hardcoded User class (the latter just until django 1.8).
class Meta(UserCreationForm.Meta):
model = get_user_model()
def clean_username(self):
username = self.cleaned_data['username']
try:
self.Meta.model.objects.get(username=username)
except self.Meta.model.DoesNotExist:
return username
raise forms.ValidationError(
self.error_messages['duplicate_username'],
code='duplicate_username',
)
Before creating a custom user model, a first migration must be performed. Then install the application of your user model and add the AUTH_USER_MODEL.
As well:
class UserForm(UserCreationForm):
class Meta:
model = User
fields = ("username",)
and
python manage.py migrate auth
python manage.py migrate
On Django 1.11 I had to do this after following instructions in docs https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#substituting-a-custom-user-model
# create default database:
./manage.py migrate
# create my custom model migration:
# running `./manage.py makemigrations` was not enough
./manage.py makemigrations books
# specify one-off defaults
# create table with users:
./manage.py migrate
Just do the following flow
$ django-admin createproject <your project name>
under <your project dict> type django-admin createapp <app name>
under <app name>/admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
Go to the root project. Then $python manage.py migrate
Then it asks for username and password
Just perform migrations before registering the user.
theres four steps for adding a custom user model to django
Create a CustomUser model
update project/settings.py AUTH_USER_MODEL
customize UserCreationForm & UserChangeForm
add the custom user model to admin.py
you missed customize forms , add the CustomUser and CustomUserAdmin to admin.site.register() , then makemigrations nd migrate .
#proj_app/forms.py
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = ('email','username',)
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
fields = ('email', 'username',)
#proj_app/admin.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreationForm , CustomUserChangeForm
CustomUser = get_user_model()
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['email','username',]
admin.site.register(CustomUser, CustomUserAdmin)
here we extend the existing UserAdmin into CustomUserAdmin and tell django to use our new forms, custom user model, and list only the email and username of a user also we could add more of existing User fields to list_display
I have no idea what I did wrong but got to the point where I decided to clear the whole database. So I ran the command:
python manage.py flush
After that my database was clear then I ran the commands;
python manage.py makemigrations
python manage.py migrate
then:
python manage.py createsuperuser
That worked for me.
I have also faced the same problem "no such table: auth_user" when I was trying to deploy one of my Django website in a virtual environment.
Here is my solution which worked in my case:
In your settings.py file where you defined your database setting like this:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(os.getcwd(), 'db.sqlite3'),
}
}
just locate your db.sqlite3 database or any other database that you are using and write down a full path of your database , so the database setting will now look something like this ;
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': '/home/django/django_project/db.sqlite3',
}
}
I hope that your problem will resolve now.
python manage.py makemigrations then → python manage.py migrate fixes it.
Assuming Apps defined/installed in settings.py exist in the project directory.
Please check how many python instances are running in background like in windows go--->task manager and check python instances and kill or end task i.e kill all python instances. run again using "py manage.py runserver" command.
i hope it will be work fine....
If You did any changes in project/app then execute:
python manage.py migrate
python manage.py makemigrations
python manage.py createsuperuser
call these command
python manage.py makemigrations
python manage.py migrate

django-oscar RuntimeError: conflicting models

Version Info: Python 2.7, Django 1.9, Oscar Commerce - VERSION = (1.3)
I am trying to customize Products and few other models in the catalogue app following the documentation.
I have forked catalogue app (to myproject/forked_apps/catalogue) as per documentation documentation and did this in models.py:
from django.db import models
from oscar.apps.catalogue.abstract_models import AbstractProduct
class Product(AbstractProduct):
is_active = models.BooleanField(default=False)
from oscar.apps.catalogue.models import *
I have already included the modified catalogue app, in the INSTALLED_APPS in settings.py as an argument for get_core_apps function, as stated in docs (so my local app is replacing the original app from Oscar).
INSTALLED_APPS = [
...
] + get_core_apps(['forked_apps.catalogue'])
Migrations are also copied from oscar.apps.catalogue to my local app.
When I'm trying to make migrations I'm getting this error all the time:
RuntimeError: Conflicting 'product_product_options' models in application 'catalogue': <class 'oscar.apps.catalogue.models.Product_product_options'> and <class 'forked_apps.catalogue.models.Product_product_options'>.
I tried to remove all migrations from my local catalogue app (the I copied before from Oscar app), then it works, but all new migrations are created in Oscar source code folder, but I need them to be in my project...
How do I get over this error ?
Make sure you're using the following wherever you use the Product model:
from oscar.core.loading import get_model
Product = get_model('catalogue', 'Product')
if you, in some place of your code write an import just like this:
from oscar.apps.catalogue.models import Product
you will ran into this issue.

Django 1.5.1 - Admin.py missing while running startapp

I've been following the DjangoProject tutorial. When I run python manage.py startapp newapp while in the same directory as manage.py. In the newapp directory I see init.py, models.py, tests.py, and views.py but not admin.py file. Where is admin.py?
I am running Django 1.5.1 in Windows 8
You have to create an admin.py file.
you don't necessarily need an admin.py file,
just import the admin module in your models.py file,
from django.contrib import admin
and for each model do the following:
admin.site.register(model1)
admin.site.register(model2)
However, this is not best practice, but since it's just a tutorial, it will work.
You also need to uncoment the relevant lines in the urls.py file
I think I had the same frustrations following the DjangoProject tutorial - however, when I cross-referenced it with with the DjangoBook tutorial (for the same version, I believe, 1.5.1), I found that an admin.py file was not necessarily created after a python manage.py startapp xyz command -- moreover, I also uncommented all of the admin options in urls.py, views.py, and settings.py - so a bit of a mix of what Neal and Ibrahim said
You have to create your own admin.py file in the app if you want it. Indeed, this file is optionnal and isn't created by startapp.
If you want a default template to begin your admin.py, it should be:
from django.contrib import admin
from models import Model1, Model2
class Model2Admin(admin.ModelAdmin):
list_display = ('title', 'content', 'date')
# Just an example, chekc docs and tutorials for more info.
admin.site.register(Model1)
admin.site.register(Model2, Model2Admin)
The reason there is no default admin.py is because you don't have any models yet when you create your new application; so there is nothing to add to the admin section.
Further, you may not want to admin all the models in your application; or you may be creating an application that does not need any admin hookups; or you may not be using the admin application at all in your project.
Since django cannot decide this for you, there is no default admin.py generated.
To create one, if you are following the tutorial - simply keep reading and in part two you'll create the admin.py file when you learn about the admin contrib app and how to integrate it with your custom models.

Django South, add new model

For some reason, when I add a new model and use Django South to sync the database by: /manage.py schemamigration myapp --auto and then the migrate line, I still can't see the model on the admin page.
South does say that it added the model though.. so I'm not sure what's going on..
Any thoughts?
Just because you created the model and synced it, does not mean it gets added to the admin page automatically. You must create an admin.py file in your app directory that contains
from django.contrib import admin
from .models import MyModel
admin.site.register(MyModel)
and make sure you have admin.site.autodiscover() in your main urls.py
This should all be covered in the tutorial pages for Django. Go back and RTM.