I am following a tutorial online for Django. The presenter loads in random data as follows:
for i in xrange(100): Vote(link = Link.objects.order_by('?')[0],voter=a).save()
From what I could understand, it goes from 0 to 100 and creates a new vote. The vote object has a link object. I don't understand what the order_by('?') means.
Here is the model.py file:
from django.db import models
from django.contrib.auth.models import User
from django.db.models import Count
class LinkVoteCountManager(models.Manager):
def get_query_set(self):
return super(LinkVoteCountManager, self).get_query_set().annotate(
votes=Count('vote')).order_by("-votes")
class Link(models.Model):
title = models.CharField("Headline", max_length=100)
submitter = models.ForeignKey(User)
submitted_on = models.DateTimeField(auto_now=True)
rank_score = models.FloatField(default=0.0)
url = models.URLField("URL", max_length=250, blank=True)
description = models.TextField(blank=True)
with_votes = LinkVoteCountManager()
objects = models.Manager()
def __unicode__(self):
return self.title
class Vote(models.Model):
voter = models.ForeignKey(User)
link = models.ForeignKey(Link)
def __unicode__(self):
return "%s voted %s" %(self.voter.username, self.link.title)
Related
The field which is specified in my models file is not included in the GraphiQL, I have tried to rename the field, delete it and define it again, even changing the type of field also updating the graphene-django package. None of these I have mentioned didn't work. The name of the field I can't get is named book
models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from books.models import Book
class Borrowing(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
book = models.OneToOneField(Book, null=True, on_delete=models.CASCADE)
date = models.DateTimeField(default=timezone.now)
returned = models.BooleanField(default=False)
date_borrowed = models.CharField(blank=True, null=True, max_length=50)
date_returned = models.CharField(blank=True, null=True, max_length=50)
class Meta:
ordering = ['-date']
def __str__(self):
return f'{self.user.username} borrowed {self.book.title}'
schema.py
import graphene
from .mutations.borrowings import *
from backend.functions import pagination
PAGE_SIZE = 12
class BorrowingMutation(graphene.ObjectType):
borrow_book = BorrowBook.Field()
return_book = ReturnBook.Field()
class BorrowingQuery(graphene.ObjectType):
borrowings = graphene.List(BorrowingType)
users_borrowings = graphene.List(BorrowingType, page=graphene.Int())
def resolve_borrowings(self, info):
return Borrowing.objects.all()
def resolve_users_borrowings(self, info, page):
user = info.context.user
borrowings = Borrowing.objects.filter(user=user, returned=False)
borrowings = pagination(PAGE_SIZE, page, borrowings)
return borrowings
Type
class BorrowingType(DjangoObjectType):
class Meta:
model = Borrowing
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()
I just started out django and python so bear with me. (Just a newbie)
I have 3 models Programme, Module and Lecture.
Programme has a variable 'code' which is a foreign key to module.
Module has in turn also a variable 'code' which is a foreign key to lecture.
In lecture I have implemented a function to get dynamic path for uploading files based on the 'code' of programme, 'code' of module and 'title' of lecture.
Here is a snippet of my models.py
from django.db import models
class Programme(models.Model):
code = models.CharField(blank=True, max_length=20, primary_key=True)
title = models.CharField(blank=True, max_length=120)
synopsis = models.TextField(blank=True)
pub_date = models.DateTimeField(blank=True, auto_now=False, auto_now_add=True)
def get_programme_code(self):
return self.code
def __str__(self):
return self.title
class Module(models.Model):
code = models.CharField(blank=True, max_length=20, primary_key=True)
programme = models.ForeignKey(Programme, on_delete=models.CASCADE)
title = models.CharField(blank=True, max_length=120)
synopsis = models.TextField(blank=True)
pub_date = models.DateTimeField(blank=True, auto_now=False, auto_now_add=True)
def get_module_code(self):
return self.code
def __str__(self):
return self.title
class Lecture(models.Model):
def get_upload_to(self):
return 'uploads/%s/%s/%s/%s' % (Programme().get_programme_code(),Module().get_module_code,self.title,filename)
title = models.SlugField(max_length=100)
module = models.ForeignKey(Module, on_delete=models.CASCADE)
lecture_pdf = models.FileField(upload_to=get_upload_to)
lecture_video = models.FileField(upload_to=get_upload_to)
def __str__(self):
return self.title
I know that there is something wrong with my code by the way of accessing 'code's from programme and modules but I cannot figure it out.
And here is a snippet of my unit testing of the models.
from django.test import TestCase
from module_content.models import Programme, Module, Lecture
from django.utils import timezone
from django.core.urlresolvers import reverse
class ProgrammeTest(TestCase):
def create_programme(self, code="E318", title="Computer Science", synopsis="Englobes all computer related fields"):
return Programme.objects.create(code =code, title=title, synopsis=synopsis, pub_date=timezone.now())
def test_programme_creation(self):
t = self.create_programme()
self.assertTrue(isinstance(t, Programme))
self.assertEqual(t.__str__(), t.title)
def test_get_programme_code(self):
t = self.create_programme()
self.assertEqual(t.get_programme_code(), t.code)
class ModuleTest(TestCase):
def create_module(self, code="CSE2233", title="Computer Networks", synopsis="About data transmission"):
v = ProgrammeTest().create_programme()
return Module.objects.create(code=code, programme=v, title=title, synopsis=synopsis, pub_date=timezone.now())
def test_module_creation(self):
t = self.create_module()
self.assertTrue(isinstance(t, Module))
self.assertEqual(t.__str__(), t.title)
class LectureTest(TestCase):
def create_lecture(self, title="Lecture 1"):
t = ModuleTest().create_module()
return Lecture.objects.create(title=title, module=t)
def test_lecture_creation(self):
s = self.create_lecture()
self.assertTrue(isinstance(s, Lecture))
self.assertEqual(s.__str__(), s.title)
def test_get_upload_to(self):
s = self.create_lecture()
self.assertEqual( s.get_upload_to(), 'uploads/E318/CSE2233/lecture-1')
I put the field of title for lecture to be a slugfield, so does django put it automatically as a slug ?
I tried the slugfield and it just return the title as "Lecture 1" instead of "lecture-1", or maybe I'm missing something.
So how can I access the foreign keys from the models and test it that the dynamic upload path is working properly?
I just needed to access the other models by their foreign keys such as self.module.programme.code - to retrieve the code of the programme.
I really need somebody to explain/show me how I can achieve a TabularInline display in the django admin console of my example. Could somebody help me out?
My models are as follows:
from django.db import models
class Player(models.Model):
player_id = models.IntegerField(primary_key=True)
team = models.ForeignKey(Team)
player_name = models.CharField(max_length=140)
position = models.CharField(max_length=10)
def __str__(self):
return '%s' % (self.player_name)
class MatchdayStats(models.Model):
MATCHDAY_STATS_ID = models.AutoField(primary_key=True)
appeared = models.BooleanField(default=False)
goal = models.IntegerField(default=0)
minutes_under_60 = models.BooleanField(default=False)
minutes_60 = models.BooleanField(default=False)
assist = models.IntegerField(default=0)
def __str__(self):
return '%s' % (self.MATCHDAY_STATS_ID)
class PlayerGameweekStats(models.Model):
PLAYER_GAMEWEEK_ALLSTATS_ID = models.AutoField(primary_key=True)
player = models.ForeignKey(Player)
gameweek = models.ForeignKey('fixturesresults.Gameweek')
matchday_stats = models.ForeignKey(MatchdayStats)
def __str__(self):
return '%s (gw=%s,msid=%s)' % (self.player.player_name,self.gameweek.GAMEWEEK_ID,self.matchday_stats.MATCHDAY_STATS_ID)
I would like there to be a tabular display for the PlayerGameweekStats model, where you can enter MatchdayStats fields for each player.
The admin code below causes a Foreign Key error <class 'playerteamstats.models.MatchdayStats'> has no ForeignKey to <class 'playerteamstats.models.PlayerGameweekStats'>
class StatsInLine(admin.TabularInline):
model = MatchdayStats
class PlayerGameweekStatsAdmin(admin.ModelAdmin):
list_display = ('player', 'gameweek')
exclude = ('gameweek')
inlines = [
StatsInLine,
]
admin.site.register(PlayerGameweekStats, PlayerGameweekStatsAdmin)
To build TabularInline models need to be connected with ForeignKey.
From Django docs example:
models.py:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=100)
admin.py:
from django.contrib import admin
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
In you case you need to have ForeignKey to PlayerGameweekStats in MatchdayStats.
Is it possible to have a field in a Django model which does not get stored in the database.
For example:
class Book(models.Model):
title = models.CharField(max_length=75)
description models.CharField(max_length=255, blank=True)
pages = models.IntegerField()
none_db_field = ????
I could then do
book = Book.objects.get(pk=1)
book.none_db_field = 'some text...'
print book.none_db_field
Thanks
As long as you do not want the property to persist, I don't see why you can't create a property like you described. I actually do the same thing on certain models to determine which are editable.
class Email(EntryObj):
ts = models.DateTimeField(auto_now_add=True)
body = models.TextField(blank=True)
user = models.ForeignKey(User, blank=True, null=True)
editable = False
...
class Note(EntryObj):
ts = models.DateTimeField(auto_now_add=True)
note = models.TextField(blank=True)
user = models.ForeignKey(User, blank=True, null=True)
editable = True
Creating a property on the model will do this, but you won't be able to query on it.
Example:
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def _get_full_name(self):
return "%s %s" % (self.first_name, self.last_name)
def _set_full_name(self, combined_name):
self.first_name, self.last_name = combined_name.split(' ', 1)
full_name = property(_get_full_name)
full_name_2 = property(_get_full_name, _set_full_name)
Usage:
from mysite.models import Person
a = Person(first_name='John', last_name='Lennon')
a.save()
a.full_name
'John Lennon'
# The "full_name" property hasn't provided a "set" method.
a.full_name = 'Paul McCartney'
Traceback (most recent call last):
...
AttributeError: can't set attribute
# But "full_name_2" has, and it can be used to initialise the class.
a2 = Person(full_name_2 = 'Paul McCartney')
a2.save()
a2.first_name
'Paul'
To make it an instance variable (so each instance gets its own copy), you'll want to do this
class Book(models.Model):
title = models.CharField(max_length=75)
#etc
def __init__(self, *args, **kwargs):
super(Foo, self).__init__(*args, **kwargs)
self.editable = False
Each Book will now have an editable that wont be persisted to the database
If you want i18n support:
# Created by BaiJiFeiLong#gmail.com at 2022/5/2
from typing import Optional
from django.db import models
from django.utils.translation import gettext_lazy as _
class Blog(models.Model):
title = models.CharField(max_length=128, unique=True, verbose_name=_("Title"))
content = models.TextField(verbose_name=_("Content"))
_visitors: Optional[int] = None
#property
def visitors(self):
return self._visitors
#visitors.setter
def visitors(self, value):
self._visitors = value
visitors.fget.short_description = _("Visitors")