Django-celery IntegrityError Column name not unique - django

I have this simple model that acts like a rsync config that is used to pre fill in the fields for a celery periodic task. The first time i create a new rsync config trough the model everything is okay and a new periodic task is being created without a problem. When i try and alter certain fields that will change the task fields such as task arguments, I'm getting a "IntegrityError column name is not unique" I feel that it has something to do with the model save method but im not sure how to get it Right. anyone got some ideas?
here is the model:
from django.forms import ModelForm
from djcelery.models import IntervalSchedule
from djcelery.models import PeriodicTask, IntervalSchedule
INTERVAL=(
('every=5','period 5 minutes'),
)
class Customer(models.Model):
"""(Customer description)"""
customername = models.CharField(blank=True, max_length=30)
emailaddress = models.EmailField()
phonenumber = models.CharField(blank=True, max_length=10)
class Meta:
verbose_name_plural = "Customer"
def __unicode__(self):
return self.customername
class RsyncConfig(models.Model):
"""(RsyncConfig description)"""
cname = models.ForeignKey(Customer)
rsyncname = models.CharField(blank=True, max_length=255)
interval=models.CharField(max_length=8,choices=INTERVAL)
fromip = models.IPAddressField(blank=True)
source_dir = models.CharField(blank=True, max_length=255)
destination_dir = models.CharField(blank=True, max_length=255)
rsync_args = models.CharField(blank=True, max_length=255)
class Meta:
verbose_name_plural = "Rsync Config"
def __unicode__(self):
return self.cname.customername
And here is the admin.py form.
from django.contrib import admin
from django import forms
from djcelery.models import PeriodicTask, IntervalSchedule
from newrsync.models import Customer,RsyncConfig
class CustomerAdmin(admin.ModelAdmin):
class Meta:
model = Customer
class RsyncConfigAdminForm(forms.ModelForm):
list_display = ('customername', 'rsyncname','source_dir','destination_dir')
class Meta:
model = RsyncConfig
def __init__(self, *args, **kwargs):
super(RsyncConfigAdminForm,self).__init__(*args, **kwargs)
def save(self, commit=True):
interval = IntervalSchedule.objects.get(every=5,period="minutes")
model = super(RsyncConfigAdminForm, self).save(commit = False)
model.cname = self.cleaned_data['cname']
model.rsyncname = self.cleaned_data['rsyncname']
model.fromip = self.cleaned_data['fromip']
model.source_dir = self.cleaned_data['source_dir']
model.destination_dir = self.cleaned_data['destination_dir']
model.rsync_args = self.cleaned_data['rsync_args']
if commit:
model.save()
PeriodicTask.objects.get_or_create(
interval=interval,
task='apps.mftconfig.tasks.rsync_proc',
args=['rsync',
model.rsync_args,
model.source_dir,
model.destination_dir],
kwargs = {},
name = (model.cname," ",model.rsyncname),
enabled=False
)
return model
class RsyncConfigAdmin(admin.ModelAdmin):
form = RsyncConfigAdminForm
list_display = ('cname', 'rsyncname','source_dir','destination_dir')
admin.site.register(Customer,CustomerAdmin)
admin.site.register(RsyncConfig,RsyncConfigAdmin)

I basically ended up doing a delete of the object right before i save a new version.It's Not perfect but at least i circumvent the unique restrain in the PeriodicTask model and now let's hope it won't bite me in the ass later on.
If anyone has any suggestions, please! ;-)
class RsyncConfigAdminForm(forms.ModelForm):
list_display = ('customername','rsyncname','source_dir','destination_dir')
class Meta:
model = RsyncConfig
def __init__(self, *args, **kwargs):
super(RsyncConfigAdminForm,self).__init__(*args, **kwargs)
def save(self, commit=True):
instance = super(RsyncConfigAdminForm, self).save(commit = False)
instance.customername = self.cleaned_data['customername']
instance.rsyncname = self.cleaned_data['rsyncname']
instance.fromip = self.cleaned_data['fromip']
instance.source_dir = self.cleaned_data['source_dir']
instance.destination_dir = self.cleaned_data['destination_dir']
instance.rsync_args = self.cleaned_data['rsync_args']
interval = IntervalSchedule.objects.get(every=5,period="minutes")
p=PeriodicTask.objects.filter(name=instance.rsyncname)
p.delete()
PeriodicTask.objects.get_or_create(
interval=interval,
task='apps.mftconfig.tasks.rsync_proc',
args=['rsync',
instance.rsync_args,
instance.source_dir,
instance.destination_dir],
kwargs = {},
name = (instance.rsyncname),
enabled=True
)
if commit:
instance.save()
return instance

Related

django serializer error: images_data = self.context['request'].FILES KeyError: 'request'

models.py
#
from django.db import models
from user.models import User
from chat.models import TradeChatRoom, AuctionChatRoom
class Goods(models.Model):
class Meta:
db_table = 'Goods'
ordering = ['-created_at'] # 일단 추가해뒀습니다
seller = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sell_goods')
buyer = models.ForeignKey(User, on_delete=models.CASCADE, related_name='buy_goods', null=True)
trade_room = models.ForeignKey(TradeChatRoom, on_delete=models.CASCADE)
auction_room = models.ForeignKey(AuctionChatRoom, on_delete=models.CASCADE)
title = models.CharField(max_length=256)
content = models.TextField()
category = models.CharField(max_length=32)
status = models.BooleanField(null=True)
predict_price = models.IntegerField()
start_price = models.IntegerField()
high_price = models.IntegerField(null=True)
start_date = models.DateField(null = True)
start_time = models.DateTimeField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
like = models.ManyToManyField(User, related_name='like_goods', null=True)
class GoodsImage(models.Model):
class Meta:
db_table = "GoodsImage"
goods = models.ForeignKey(Goods, on_delete=models.CASCADE)
image = models.ImageField(upload_to='goods/')
serializer.py
from rest_framework import serializers
from .models import Goods,GoodsImage
class GoodImageSerializer(serializers.ModelSerializer):
image = serializers.ImageField(use_url=True)
def get_image(self, obj):
image = obj.goods_set.all()
return GoodsPostSerializer(instance=image, many = True, context = self.context)
class Meta:
model = GoodsImage
field =('image',)
class GoodsPostSerializer(serializers.ModelSerializer):
image = GoodImageSerializer(many=True, read_only = True)
class Meta:
model = Goods
fields = (
'seller', 'buyer','auction_room','title','content',
'category','status','predict_price','start_price','high_price',
'trade_room','start_date','start_time','created_at','like','image',
)
read_only_fields = ("seller",)
def create(self, validated_data):
goods = Goods.objects.create(**validated_data)
images_data = self.context['request'].FILES
for image_date in images_data.getlist('image'):
GoodsImage.objects.create(goods = goods, image = image_date)
return goods
error
images_data = self.context['request'].FILES
KeyError: 'request'
I want to save multiple images, but I keep getting an error. I don't know what to do anymore.
I searched for a method and followed it, but it seems that I am the only one who gets an error.
Please help if you know how to solve this problem.
And I want to know if it is correct to put it in a list like "image":["12.jpeg,"13.jpeg] when inserting multiple images through postman.
It's hard not being able to solve this problem. please help me if you know the answer
Change GoodImageSerializer calling this:
GoodImageSerializer(instance=images, many = True, context={'request': request})
Then change your GoodsPostSerializer's create method like this:
def get_image(self, obj):
image = obj.goods_set.all()
request = self.context['request']
return GoodsPostSerializer(instance=image, many = True, context={'request': request})

Saving / accessing fields from Class methods (Django)

Appologies for the beginner question and/or stupidity - I'm learning as I go.... I'm trying to pass a user entered url of a PubMed article to access the metadata for that article. I'm using the following code, but I cannot access anything form the save method in he 'Entry' model. For example in my html form I can display {{entry.date_added }} in a form but not {{ entry.title}}. I suspect it's a simple answer but not obvious to me. Thanks for any help.
models.py
from django.db import models
from django.contrib.auth.models import User
import pubmed_lookup
from django.utils.html import strip_tags
class Topic(models.Model):
"""Broad topic to house articles"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
"""Return a string representation of the model"""
return self.text
class Entry(models.Model):
"""Enter and define article from topic"""
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
pub_med_url = models.URLField(unique=True)
date_added = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
query = self.pub_med_url
email = "david.hallsworth#hotmail.com"
lookup = pubmed_lookup.PubMedLookup(query, email)
publication = pubmed_lookup.Publication(lookup)
self.title = strip_tags(publication.title)
self.authors = publication.authors
self.first_author = publication.first_author
self.last_author = publication.last_author
self.journal = publication.journal
self.year = publication.year
self.month = publication.month
self.day = publication.day
self.url = publication.url
self.citation = publication.cite()
self.mini_citation = publication.cite_mini()
self.abstract = strip_tags(publication.abstract)
super().save(*args, **kwargs)
class Meta:
verbose_name_plural = 'articles'
def __str__(self):
return "{} - {} - {} - {} [{}]".format(self.year,
self.first_author, self.journal, self.title, str(self.pmid), )
In Django ORM, you have to manually specify all fields that need to be saved. Simply saving it as self.foo = bar in the save method is stored in the Entry instance object (=in memory), but not in the database. That is, there is no persistence. Specify all the fields that need to be saved in the model and run python manage.py makemigrations,python manage.py migrate. Assigning fields to the model is actually the task of designing the relational database.
class Entry(models.Model):
"""Enter and define article from topic"""
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
pub_med_url = models.URLField(unique=True)
date_added = models.DateTimeField(auto_now_add=True)
title = models.CharField(...)
authors = models.CharField(...)
...
def assign_some_data_from_pubmed(self):
email = "david.hallsworth#hotmail.com"
lookup = pubmed_lookup.PubMedLookup(query, email)
publication = pubmed_lookup.Publication(lookup)
self.title = strip_tags(publication.title)
self.authors = publication.authors
self.first_author = publication.first_author
self.last_author = publication.last_author
self.journal = publication.journal
self.year = publication.year
self.month = publication.month
self.day = publication.day
self.url = publication.url
self.citation = publication.cite()
self.mini_citation = publication.cite_mini()
self.abstract = strip_tags(publication.abstract)
Usage:
entry = Entry(...)
entry.assign_some_data_from_pubmed()
entry.save()

How to fetch certain field value of related models object and save it to another?

My models Book and ReadList related and I can use them on Django Admin but I want to fetch bookPageCount field of selected object and save it to pageCount field of new object when save.
from django.db import models
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
# Create your models here.
class Book(models.Model):
bookname = models.CharField(max_length=200, verbose_name='Kitap Adı')
bookAuthor = models.CharField(max_length=100, verbose_name='Yazar Adı')
bookPublisher = models.CharField(max_length=100, verbose_name='Yayın Evi')
bookPageCount = models.PositiveIntegerField(verbose_name='Sayfa Sayısı')
bookAddDate = models.DateField(verbose_name='Kitaplığa Eklenme Tarihi')
class Meta:
verbose_name = 'Kitap'
verbose_name_plural = 'Kitaplar'
def __str__(self):
return self.bookname
class ReadList(models.Model):
bookName = models.ForeignKey('kitaplik.Book', related_name='book', on_delete=models.CASCADE, verbose_name='Kitap Adı')
readerName = models.ForeignKey('ogrenciler.Students', on_delete=models.CASCADE, related_name='readerName', verbose_name='Okuyan Kişi')
dateOfRead = models.DateField(verbose_name='Okuma Tarihi')
pageCount = models.PositiveIntegerField(verbose_name='Sayfa Sayısı',blank=True, null=True)
class Meta:
verbose_name = 'Okuma Günlüğü'
#receiver(post_save, sender=ReadList)
def get_pageCount(sender, instance, **kwargs):
instance.pageCount = instance.Book.bookPageCount
instance.save
EDIT: Changes been made after Higor's reminder but I still have problem as the same. The error I get is 'ReadList' object has no attribute 'Book'
I think you've mistaken some names.
#receiver(post_save, sender=ReadList)
def get_pageCount(sender, instance, **kwargs):
instance.pageCount = instance.book.bookpageCount
instance.save()
bookName is the field name
#receiver(post_save, sender=ReadList)
def get_pageCount(sender, instance, **kwargs):
instance.pageCount = instance.bookName.bookPageCount
instance.save()

showing entries based on selection type in django

my question is i want to show only particular titles under music_track (musicmodel)field when type = track(title model) in my django admin site
class album(models.Model):
def get_autogenerated_code():
last_id = album.objects.values('id').order_by('id').last()
if not last_id:
return "AL-"+str(0)
return "AL-"+str(last_id['id'])
album_name = models.CharField( max_length=150, blank=False )
music_track = models.ManyToManyField("title")
def __str__(self):
return (self.album_name)
class Meta:
verbose_name = "Album"
verbose_name_plural = "Albums"
class title(models.Model):
def get_autogenerated_code():
last_id = title.objects.values('id').order_by('id').last()
if not last_id:
return "TT-"+str(0)
return "TT-"+str(last_id['id'])
upc_code = models.CharField(max_length=15, default="N/A", blank=False)
display_name = models.CharField(max_length=150, blank=False)
type = models.ForeignKey(Asset_Type, on_delete=models.CASCADE, null=True)
def __str__(self):
return (self.display_name+ " " +self.code)
admin.site.register( [album, title] )
From your question, I am understanding that while creating an album in your admin panel, you require that the music_track should only show the titles having type as track. My solution for this is:
In your admin.py file
from .models import title, album, Asset_type
class AlbumForm(forms.ModelForm):
class Meta:
model = Product
fields = ('album_name', 'music_track', )
def __init__(self, user, *args, **kwargs):
super(AlbumForm, self).__init__(*args, **kwargs)
type = Asset_type.objects.get(type='track')
self.fields['music_track'].queryset = Title.objects.filter(type=type)
class MyModelAdmin(admin.ModelAdmin):
form = AlbumForm
admin.site.register(album, MyModelAdmin)
Maybe this can give you the idea you need.

Django REST Framework (DRF): Set current user id as field value

I have model NewsModel and 2 serializers for him:
models.py
class NewsModel(models.Model):
title = models.CharField('Заголовок', max_length=255, help_text='Максимальная длина - 255 символов')
announce = models.TextField('Анонс', help_text='Краткий анонс новости')
author = models.ForeignKey(settings.AUTH_USER_MODEL, help_text='Автор новости', related_name='news')
full_text = models.TextField('Полный текст новости', help_text='Полный текст новости')
pub_date = models.DateTimeField('Дата публикации', auto_now_add=True, default=timezone.now, help_text='Дата публикации')
def comments_count(self):
return NewsComment.objects.filter(news=self.id).count()
def get_author_full_name(self):
return self.author.get_full_name()
class Meta:
db_table = 'news'
ordering = ('-pub_date',)
serilizers.py:
from rest_framework import serializers
from .models import NewsModel
from extuser.serializers import UserMiniSerializer
class NewsReadSerializer(serializers.ModelSerializer):
author = UserMiniSerializer()
class Meta:
model = NewsModel
fields = ('id', 'title', 'announce', 'comments_count', 'reviews', 'author_name')
def get_author_full_name(self, obj):
return obj.get_author_full_name()
class NewsWriteSerializer(serializers.ModelSerializer):
def validate_author(self, value):
value = self.request.user.id
return value
class Meta:
model = NewsModel
I select serializers in the api.py:
class NewsList(ListCreateAPIView):
queryset = NewsModel.objects.order_by('-pub_date')
def get_serializer_class(self, *args, **kwargs):
if self.request.method == 'GET':
return NewsReadSerializer
return NewsWriteSerializer
class Meta:
model = NewsModel
But when I will create NewsModel item, I see Error 400: Bad request [{'author': 'This field is required'}]
How I can set current user id as NewsItem.author value on creating new item?
I don't think you're using the serializer properly. A better practice to set request related data is to override perform_create in your view:
def perform_create(self, serializer):
serializer.save(author=self.request.user)
def perform_update(self, serializer):
serializer.save(author=self.request.user)
and then set your author serializer to read-only:
author = UserMiniSerializer(read_only=True)
this way you can simply use one single NewsSerializer for both read and write actions.
In new DRF you can write
owner = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
See http://www.django-rest-framework.org/api-guide/validators/#currentuserdefault
In DRF version prior 3 field must be declader with allow_null=True and default=None. DRF don't run checking fields without this params. Result code:
class NewsReadSerializer(serializers.ModelSerializer):
"""
Serializer only for reading.
author field serialized with other custom serializer
"""
author = UserMiniSerializer()
class Meta:
model = NewsModel
fields = ('id', 'title', 'announce', 'comments_count', 'reviews', 'author', 'pub_date',)
class NewsWriteSerializer(serializers.ModelSerializer):
"""
Serializer for creating and updating records.
author here is the instance of PrimaryKeyRelatedField, linked to all users
"""
author = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all(), # Or User.objects.filter(active=True)
required=False,
allow_null=True,
default=None
)
# Get the current user from request context
def validate_author(self, value):
return self.context['request'].user
class Meta:
model = NewsModel
fields = ('title', 'announce', 'full_text', 'author',)
I would try something like this:
your models.py
class NewsModel(models.Model):
title = models.CharField(
'Заголовок', max_length=255,
help_text='Максимальная длина - 255 символов')
announce = models.TextField('Анонс',
help_text='Краткий анонс новости')
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
help_text='Автор новости', related_name='news')
full_text = models.TextField(
'Полный текст новости',
help_text='Полный текст новости')
pub_date = models.DateTimeField(
'Дата публикации', auto_now_add=True,
default=timezone.now, help_text='Дата публикации')
def comments_count(self):
return NewsComment.objects.filter(news=self.id).count()
def get_author_full_name(self):
return self.author.get_full_name()
class Meta:
db_table = 'news'
ordering = ('-pub_date',)
serializers.py
(ref.: http://www.django-rest-framework.org/api-guide/validators/#currentuserdefault)
from <yourapp>.models import NewsModel
from rest_framework import serializers
class NewsModelSerializer(serializers.ModelSerializer):
author = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model = NewsModel
Also you should set settings.py to something like this:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',)
}