Django + Postgres + UUID - python

UPDATE:
I have got it to work!
What I did was:
Deleted the app
Went into Postgres Admin and deleted the Schema for that app
Created the app again (using a diff name)
Created the Models, URLs, Admin Registering, Views
So I've been trying to add a UUID field to my model, to use it in my URL but I keep getting this error
django.db.utils.ProgrammingError: column "id" is of type bigint but expression is of type uuid
LINE 1: ..._book" ("id", "title", "author", "price") VALUES ('f6b15400-...
^
HINT: You will need to rewrite or cast the expression.
Here is my models.py:
from django.db import models
import uuid
from django.urls import reverse
# Create your models here.
class Book(models.Model):
id = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('book_detail', args=[str(self.id)])
Here is the views.py:
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from .models import Book
# Create your views here.
class BookListView(ListView):
model = Book
template_name = 'books/book_list.html'
context_object_name = 'book_list'
class BookDetailView(DetailView):
model = Book
template_name = 'books/book_detail.html'
context_object_name = 'book'
Here is the urls.py:
from django.urls import path
from .views import BookListView, BookDetailView
urlpatterns = [
path('', BookListView.as_view(), name='book_list'),
path('<uuid:pk>/', BookDetailView.as_view(), name='book_detail'),
]

First add the uuid field as a normal field with a different name:
from django.db import models
import uuid
from django.urls import reverse
class Book(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, unique=True)
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
price = models.DecimalField(max_digits=6, decimal_places=2)
Run makemigrations and migrate
Now make it primary key:
class Book(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, primary_key=True)
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
price = models.DecimalField(max_digits=6, decimal_places=2)
This should generate a migration that removes the id field and makes uuid primary key (makemigrations and migrate again).
And finally:
class Book(models.Model):
id = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
price = models.DecimalField(max_digits=6, decimal_places=2)
You may have to adjust the generated migration.

Related

insert or update on table "django_admin_log" violates foreign key constraint

Trying to save a post on a django project I got this error
The above exception (insert or update on table "django_admin_log" violates foreign key constraint "django_admin_log_user_id_c564eba6_fk_auth_user_id" DETAIL: Key (user_id)=(1) is not present in table "auth_user". ) was the direct cause of the following exception:
The model:
from django.conf import settings
class Tag(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True)
author = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.TextField()
image = models.ImageField(upload_to='', blank=True, null=True)
tags = models.ManyToManyField(Tag, blank=True)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
The view:
from django.views.generic import ListView, DetailView
from django.shortcuts import get_object_or_404
from .models import Post
class BlogView(ListView):
template_name = 'base/blog.html'
queryset = Post.objects.all()
paginate_by = 2
class PostView(DetailView):
model = Post
template_name = 'base/post.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
pk = self.kwargs['pk']
slug = self.kwargs['slug']
post = get_object_or_404(Post, pk=pk, slug=slug)
context['post'] = post
return context
How can I solve this problem?
That because the django_admin_log table still contains a foreign key relation to the old auth_user table.
You need to drop this and recreate the table.
psql => DROP table django_admin_log;
For Django >= 1.7
./manage.py sqlmigrate admin 0001 | ./manage.py dbshell
And that's it :)

Upload multiple images for a single product in django

I have created some nice models in models.py for uploading multiple images in single products, for different products. The good thing it uses one image model for all products. Now i'm failing to create a perfect forms.py. May someone help me please.
from django.db import models
from django.utils.safestring import mark_safe
from ckeditor_uploader.fields import RichTextUploadingField
from mptt.fields import TreeForeignKey
from mptt.models import MPTTModel
from django.urls import reverse
from django import forms
from django.forms import ModelForm, Form, TextInput, Textarea
def get_upload_path(instance, filename):
model = instance.album.model.__class__._meta
name = model.verbose_name_plural.replace(' ', '_')
return f'{name}/images/{filename}'
class ImageAlbum(models.Model):
def default(self):
return self.images.filter(default=True).first()
def thumbnails(self):
return self.images.filter(width__lt=100, length_lt=100)
class Image(models.Model):
name = models.CharField(max_length=255)
image = models.ImageField(upload_to=get_upload_path)
default = models.BooleanField(default=False)
width = models.FloatField(default=100)
length = models.FloatField(default=100)
album = models.ForeignKey(ImageAlbum, related_name='images', on_delete=models.CASCADE)
class Product(models.Model):
title = models.CharField(max_length=20)
album = models.OneToOneField(ImageAlbum, related_name='model', on_delete=models.CASCADE)
class Vehicle(Product):
STATUS = (
('True', 'True'),
('False', 'False'),
)
brand = models.CharField(max_length=30)
price = models.DecimalField(max_digits=8, decimal_places=2)
mileage = models.IntegerField()
...

Django Forms created from Model with overfull Queryset Output

I am trying to create a ModelForm for my Model Class "Asset" in Django 3
from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
class Manufacturer(models.Model):
name = models.CharField(max_length=100)
class Asset(models.Model):
serial = models.CharField(max_length=200)
manufacturer = models.ManyToManyField(Manufacturer)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
I managed to create a Form via the following code
from django import forms
from .models import Manufacturer
class AssetForm(forms.Form):
serial = forms.CharField(max_length=150)
manufacturer = forms.ModelChoiceField(queryset=Manufacturer.objects.all().values('name'))
name = forms.CharField(max_length=200)
description = forms.TextInput()
status = forms.CharField(max_length=200)
category = forms.CharField(max_length=200)
The querySet results in a dropdown being filled out with either "{'name':'Apple'}" or "('Apple',)" depending on using values or values_list respectively. How can I just display the name itself?
Adding the following method to the model fixes the problem:
def __str__(self):
return self.name
This will return the name and only the name to the queryset.

Displaying images from model using Django

So I would like to simply show multiple images on my homepage with data from the image field of my Product model. The premise is every time I add a new Product with an image it would generate a new li tag with a new image.
I then would like when the user clicks on the image on the homepage it appears in a model window with the slug name of the product in the URL, with the rest of the Product Information throughout the template that appears in the model window.
So can anyone help guide me on how to implement this solution?
Here is what I have so far:
Thank You!
Models.py
from __future__ import unicode_literals
from django.db import models
from django.utils.translation import ugettext_lazy as _
import datetime
class Designer(models.Model):
name = models.CharField(max_length=254, blank=True, null=True)
label_name = models.CharField(max_length=254, blank=True, null=True)
description = models.TextField(null=True, blank=True)
specialites = models.CharField(max_length=254, null=True, blank=True)
image = models.ImageField(upload_to='images/designers/main',max_length=100, null=True) #For the argument upload_to, will add to the static folder and generated image will be stored in suing that path specified
#For Admin Purposes, to track and see which if still active by for administrative users only
is_active = models.BooleanField(default=True)
#Metadata
class Meta:
verbose_name = _("Designer Information")
verbose_name_plural = _("Designers")
#Helps return something meaningful, to show within the admin interface for easy interaction
def __unicode__(self):
return "{0} {1}".format(self.name, self.label_name)
class Boutique(models.Model):
name = models.CharField(max_length=254, blank=True, null=True)
address = models.CharField(max_length=255, blank=True, null=True)
city = models.CharField(max_length=50, null=True, blank=True)
state = models.CharField(max_length=2, null=True, blank=True)
zipcode = models.IntegerField(max_length=5, null=True, blank=True)
boutique_website = models.URLField(max_length=200, null=True, blank=True)
#For Admin Purposes, to track a product to see which is active by administrative users
is_active = models.BooleanField(default=True)
#Foreign Keys & other relationships
designer = models.ForeignKey(Designer)
#Metadata
class Meta:
verbose_name = _("Boutique Information")
verbose_name_plural = _("Boutiques")
#Helps return something meaningful, to show within the admin interface for easy interaction
def __unicode__(self):
return "{0}, {1}, {2}".format(self.name, self.city, self.state)
class ProductCategory(models.Model):
name = models.CharField(max_length=255L, blank=True, null=True)
slug = models.SlugField(max_length=50, unique=True, help_text='Unique value for product page URL, created from name.')
#For Admin Purposes, to track and see which if still active by for administrative users only
is_active = models.BooleanField(default=True)
#For Admin Purposes, to track when we add each product and each product was updated by administrative users
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
#Metadata
class Meta:
verbose_name = _("Product Category")
verbose_name_plural = _("Product Categories")
#Helps return something meaningful, to show within the admin interface for easy interaction
def __unicode__(self):
return "{0}".format(self.name)
class Product(models.Model):
name = models.CharField(max_length=254, blank=True, null=True)
description = models.TextField(blank=True, null=True)
color_name = models.CharField(max_length=254, null=True, blank=True)
size_types = models.CharField(max_length=7, null=True, blank=True)
product_price = models.DecimalField(max_digits=9,decimal_places=2)
old_price = models.DecimalField(max_digits=9,decimal_places=2, blank=True,default=0.00) #To show original price if, new price has been added
product_tags = models.CharField(max_length=254, null=True, blank=True, help_text='Comma-delimited set of SEO keywords for product tag area')
novelty = models.CharField(max_length=254, null=True, blank=True)
product_website = models.URLField(max_length=200, null=True, blank=True) #To show other sites to Users, where they can purchase the particular product
image = models.ImageField(upload_to='images/products/main',max_length=100, null=True) #For the argument upload_to, will add to the static folder and generated image will be stored in suing that path specified
slug = models.SlugField(max_length=255, unique=True, help_text='Unique value for product page URL, created from name.')
#This shows when each item was uploaded & by who, to the User
uploaded_by = models.CharField(max_length=254, blank=True, null=True)
uploaded_at = models.DateTimeField(auto_now=True)
#For Admin Purposes, to track and see which if still active by for administrative users only
is_active = models.BooleanField(default=True)
#Foreign Keys & other relationships
designer = models.ForeignKey(Designer)
boutique = models.ForeignKey(Boutique)
category = models.ForeignKey(ProductCategory)
#Metadata
class Meta:
verbose_name = _("Product")
verbose_name_plural = _("Products")
#Helps return something meaningful, to show within the admin interface for easy interaction
def __unicode__(self):
return "{0}".format(self.name)
Admin.py
from __future__ import unicode_literals
from django.contrib import admin
from products.models import Designer, Product, ProductCategory, Boutique
class DesignerAdmin(admin.ModelAdmin):
list_display = ["name", "label_name", "description", "specialites", "image", "is_active"]
search_fields = ["name", "label_name"]
list_per_page = 50
class ProductAdmin(admin.ModelAdmin):
list_display = ["name", "description", "color_name", "size_types", "product_price", "old_price", "product_tags", "novelty","product_website", "image", "slug", "uploaded_by", "uploaded_at", "is_active"]
search_fields = ["name", "product_price"]
list_per_page = 25
class ProductCategoryAdmin(admin.ModelAdmin):
list_display = ["name", "slug", "is_active", "created_at", "updated_at"]
search_fields = ["name"]
list_per_page = 25
class BoutiqueAdmin(admin.ModelAdmin):
list_display = ["name", "address", "city", "state", "zipcode", "boutique_website", "is_active"]
search_fields = ["name"]
list_per_page = 10
#Register Models below
admin.site.register(Boutique, BoutiqueAdmin)
admin.site.register(Designer, DesignerAdmin)
admin.site.register(Product, ProductAdmin)
admin.site.register(ProductCategory, ProductCategoryAdmin)
Forms.py
from __future__ import unicode_literals
from django import forms
from django.forms import extras, ModelForm
from products.models import Designer, Product, ProductCategory, Boutique
class DesignerForm(ModelForm):
class Meta:
model = Designer
class ProductForm(ModelForm):
class Meta:
model = Product
class BoutiqueForm(ModelForm):
class Meta:
model = Boutique
class ProductCategoryForm(ModelForm):
class Meta:
model = ProductCategory
Views.Py
from __future__ import unicode_literals
from django.http import Http404, HttpResponseForbidden
from django.shortcuts import redirect, get_object_or_404
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DetailView
from django.contrib import auth, messages
from django.contrib.sites.models import get_current_site
from django.shortcuts import render
from products.forms import ProductForm, ProductCategoryForm
from products.forms import BoutiqueForm
from products.forms import DesignerForm
from products.models import Boutique, Product, ProductCategory, Designer
class ProductView(DetailView):
model = Product
Template For Homepage
{% extends "site_base.html" %}
{% load i18n %}
{% block body %}
<div id="main" role="main">
<ul id="tiles">
<li>
<img src=" {{ object.image.url }}" />
</li>
</ul>
</div>
{% endblock %}
urls.py
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.conf.urls.static import static
from django.views.generic import TemplateView
from products.views import ProductView
from django.contrib import admin
urlpatterns = patterns('',
url(r"^$", TemplateView.as_view(template_name="homepage.html"), name="home"),
url(r"^$", ProductView.as_view(), name="list"),
)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
you can set MEDIA_URL in your settings.py then use <img src="{{ MEDIA_URL }}{{ product.image.url }}" />
IMHO you have a problem of how you access the content in the view. If you're using the formview, you should have the data available via {{ form....}} (e.g. {{form.image.url}}).
If you have the object available and you haven't redefined its alias, then you should have it via {{ object.... }}.

Implementing product upload dynamically using Django 1.6

So I am using my admin interface to add product information for different items that will be on my site. I am looking to add the product information from my models to a template view, but I would like for every time I add a new product using my admin interface, for the template to generate a new Li tag with the current product information and picture used of the entered data within the admin interface.
I have not yet implemented any template logic in my views.py yet I am stumped on how to really wrap my head around making this whole process happen. So can anyone help guide me on how to implement this solution?
Thank You!
Here is my code below:
Models.py
from __future__ import unicode_literals
from django.db import models
from django.utils.translation import ugettext_lazy as _
import datetime
class Designer(models.Model):
name = models.CharField(max_length=254, blank=True, null=True)
label_name = models.CharField(max_length=254, blank=True, null=True)
description = models.TextField(null=True, blank=True)
specialites = models.CharField(max_length=254, null=True, blank=True)
image = models.ImageField(upload_to='images/designers/main',max_length=100, null=True) #For the argument upload_to, will add to the static folder and generated image will be stored in suing that path specified
#For Admin Purposes, to track and see which if still active by for administrative users only
is_active = models.BooleanField(default=True)
#Metadata
class Meta:
verbose_name = _("Designer Information")
verbose_name_plural = _("Designers")
#Helps return something meaningful, to show within the admin interface for easy interaction
def __unicode__(self):
return "{0} {1}".format(self.name, self.label_name)
class Boutique(models.Model):
name = models.CharField(max_length=254, blank=True, null=True)
address = models.CharField(max_length=255, blank=True, null=True)
city = models.CharField(max_length=50, null=True, blank=True)
state = models.CharField(max_length=2, null=True, blank=True)
zipcode = models.IntegerField(max_length=5, null=True, blank=True)
boutique_website = models.URLField(max_length=200, null=True, blank=True)
#For Admin Purposes, to track a product to see which is active by administrative users
is_active = models.BooleanField(default=True)
#Foreign Keys & other relationships
designer = models.ForeignKey(Designer)
#Metadata
class Meta:
verbose_name = _("Boutique Information")
verbose_name_plural = _("Boutiques")
#Helps return something meaningful, to show within the admin interface for easy interaction
def __unicode__(self):
return "{0}, {1}, {2}".format(self.name, self.city, self.state)
class ProductCategory(models.Model):
name = models.CharField(max_length=255L, blank=True, null=True)
slug = models.SlugField(max_length=50, unique=True, help_text='Unique value for product page URL, created from name.')
#For Admin Purposes, to track and see which if still active by for administrative users only
is_active = models.BooleanField(default=True)
#For Admin Purposes, to track when we add each product and each product was updated by administrative users
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
#Metadata
class Meta:
verbose_name = _("Product Category")
verbose_name_plural = _("Product Categories")
#Helps return something meaningful, to show within the admin interface for easy interaction
def __unicode__(self):
return "{0}".format(self.name)
class Product(models.Model):
name = models.CharField(max_length=254, blank=True, null=True)
description = models.TextField(blank=True, null=True)
color_name = models.CharField(max_length=254, null=True, blank=True)
size_types = models.CharField(max_length=7, null=True, blank=True)
product_price = models.DecimalField(max_digits=9,decimal_places=2)
old_price = models.DecimalField(max_digits=9,decimal_places=2, blank=True,default=0.00) #To show original price if, new price has been added
product_tags = models.CharField(max_length=254, null=True, blank=True, help_text='Comma-delimited set of SEO keywords for product tag area')
novelty = models.CharField(max_length=254, null=True, blank=True)
product_website = models.URLField(max_length=200, null=True, blank=True) #To show other sites to Users, where they can purchase the particular product
image = models.ImageField(upload_to='images/products/main',max_length=100, null=True) #For the argument upload_to, will add to the static folder and generated image will be stored in suing that path specified
slug = models.SlugField(max_length=255, unique=True, help_text='Unique value for product page URL, created from name.')
#This shows when each item was uploaded & by who, to the User
uploaded_by = models.CharField(max_length=254, blank=True, null=True)
uploaded_at = models.DateTimeField(auto_now=True)
#For Admin Purposes, to track and see which if still active by for administrative users only
is_active = models.BooleanField(default=True)
#Foreign Keys & other relationships
designer = models.ForeignKey(Designer)
boutique = models.ForeignKey(Boutique)
category = models.ForeignKey(ProductCategory)
#Metadata
class Meta:
verbose_name = _("Product")
verbose_name_plural = _("Products")
#Helps return something meaningful, to show within the admin interface for easy interaction
def __unicode__(self):
return "{0}".format(self.name)
Admin.py
from __future__ import unicode_literals
from django.contrib import admin
from products.models import Designer, Product, ProductCategory, Boutique
class DesignerAdmin(admin.ModelAdmin):
list_display = ["name", "label_name", "description", "specialites", "image", "is_active"]
search_fields = ["name", "label_name"]
list_per_page = 50
class ProductAdmin(admin.ModelAdmin):
list_display = ["name", "description", "color_name", "size_types", "product_price", "old_price", "product_tags", "novelty","product_website", "image", "slug", "uploaded_by", "uploaded_at", "is_active"]
search_fields = ["name", "product_price"]
list_per_page = 25
class ProductCategoryAdmin(admin.ModelAdmin):
list_display = ["name", "slug", "is_active", "created_at", "updated_at"]
search_fields = ["name"]
list_per_page = 25
class BoutiqueAdmin(admin.ModelAdmin):
list_display = ["name", "address", "city", "state", "zipcode", "boutique_website", "is_active"]
search_fields = ["name"]
list_per_page = 10
#Register Models below
admin.site.register(Boutique, BoutiqueAdmin)
admin.site.register(Designer, DesignerAdmin)
admin.site.register(Product, ProductAdmin)
admin.site.register(ProductCategory, ProductCategoryAdmin)
Forms.py
from __future__ import unicode_literals
from django import forms
from django.forms import extras, ModelForm
from products.models import Designer, Product, ProductCategory, Boutique
class DesignerForm(ModelForm):
class Meta:
model = Designer
class ProductForm(ModelForm):
class Meta:
model = Product
class BoutiqueForm(ModelForm):
class Meta:
model = Boutique
class ProductCategoryForm(ModelForm):
class Meta:
model = ProductCategory
Views.Py
from __future__ import unicode_literals
from django.http import Http404, HttpResponseForbidden
from django.shortcuts import redirect, get_object_or_404
from django.utils.http import base36_to_int, int_to_base36
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateResponseMixin, View
from django.views.generic.edit import FormView
from django.contrib import auth, messages
from django.contrib.sites.models import get_current_site
from django.shortcuts import render
from products.forms import ProductForm, ProductCategoryForm
from products.forms import BoutiqueForm
from products.forms import DesignerForm
from products.models import Boutique, Product, ProductCategory, Designer
class ProductView(FormView):
template_name = "product_detail/product.html"
form_class = ProductForm
template_var={}
def __init__(self, *arg):
super(ProductView, self).__init__()
self.arg = arg
class ProductCategoryView(FormView):
form_class = ProductCategoryForm
template_var={}
def __init__(self, *arg):
super(ProductCategory, self).__init__()
self.arg = arg
The easiest way to do this is a simple ListView from Django's generic class-based views.
First, string up your views.py:
from django.views.generic import ListView
class ProductListView(ListView):
model = Product
template_name = 'product/list_view.html' # Edit this to whatever your template is.
Remember to edit your urls.py:
from .views import ProductListView
urlpatterns = patterns('',
...
url(r'^product/$', ProductListView.as_view(), name='list'), # Edit url path and name as desired
...
)
Then, make your template:
<div class="jumbotron">
<ul>
{% for product in products %}
<li>{{ product.name }}: {{ product.description }} <img src="{{ product.image.url }}" >
{% endfor %}
</ul>
</div>
This is a very basic template which you'll obviously want to customize. For each Product in your database, it will display the name, description, and the image. You can customize your fields as you desire.
Other potential issues:
1) Be sure you provide the correct path to your template in your ListView.
2) Set up your MEDIA_URL and other media settings to allow your Product image to display.
3) Look at other customization options in ListView (see documentation here.)

Categories