限制为每天一次的用户实例填写表格(Django)

时间:2017-08-31 00:13:06

标签: python django

我正在开发这个让人们登录的网络应用程序,并能够创建:用户,为不同类型的啤酒创建啤酒和评论。

这是我用于制作啤酒的models.py:

from django.db import models
from django.conf import settings

# Models

User = settings.AUTH_USER_MODEL

class BeerModel(models.Model):

    user = models.ForeignKey(User, default=1)
    name = models.CharField(max_length=254, default="")
    style = models.CharField(max_length=254, default="")
    ibu = models.IntegerField(default="")
    calories = models.IntegerField(default="")
    abv = models.IntegerField(default="")
    location = models.CharField(max_length=254, default="")

    class Meta:
        verbose_name_plural = 'Beers'

    def __str__(self):
        return self.name

    def avg(self):
        return

这是我的forms.py:

from django import forms
from django.contrib.auth.models import User
from .models import BeerModel, RateModel

# Forms

class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = User
        fields = ('username', 'email', 'password')
        help_texts = {
            'username': None,
        }

class NewBeerForm(forms.ModelForm):
    name = forms.CharField(label="Beer Name")
    ibu = forms.IntegerField(label="IBU")
    abv = forms.IntegerField(label="ABV")
    location = forms.CharField(label="Brewery Location")

    class Meta:
        model = BeerModel
        fields = '__all__'

这是我的views.py:

@login_required
def new_beer(request):
    if request.method == "POST":
        beer = NewBeerForm(request.POST)
        if beer.is_valid():
            beer.save(commit=True)
            return HttpResponseRedirect(reverse('beer_tracker:home'))
    else:
        beer = NewBeerForm()

    return render(request, 'beer_tracker/new_beer.html', {'beer':beer})

如您所见,要制作啤酒,您需要填写一些详细信息,包括“用户”字段。

所以我的目标是能够限制我选择的每天只能制作一杯啤酒的特定用户。

有什么想法?我正在研究芹菜,但我确信有更好的方法。

安东尼

2 个答案:

答案 0 :(得分:2)

您可能希望在创建啤酒时添加日期时间字段以存储。

class BeerModel(models.Model):

    user = models.ForeignKey(User, default=1)
    name = models.CharField(max_length=254, default="")
    style = models.CharField(max_length=254, default="")
    ibu = models.IntegerField(default="")
    calories = models.IntegerField(default="")
    abv = models.IntegerField(default="")
    location = models.CharField(max_length=254, default="")
    created = models.DateTimeField(auto_now_add=True)

然后,您必须更新视图以检查是否有一天内创建的啤酒。

from django.utils import timezone


@login_required
def new_beer(request):
    if request.method == "POST":
        yesterday = timezone.now() - timezone.timedelta(days=1)
        if BeerModel.objects.filter(user=request.user, created__gt=yesterday).exists():
            return HttpResponseForbidden()   # return a 403 status code
        beer = NewBeerForm(request.POST)
        if beer.is_valid():
            beer.save(commit=True)
            return HttpResponseRedirect(reverse('beer_tracker:home'))
    else:
        beer = NewBeerForm()

    return render(request, 'beer_tracker/new_beer.html', {'beer':beer})

答案 1 :(得分:1)

您要做的第一件事是在DateField中创建BeerModel

class BeerModel(models.Model):
    ...
    created = models.DateField(default=django.utils.timezone.now)
    # or (but see https://code.djangoproject.com/ticket/20180)
    # created = models.DateField(auto_now_add=True)

然后,如果要在数据库级别强制执行此操作,则可以创建unique_together约束:

class BeerModel(models.Model):
    ...
    class Meta:
        unique_together = ('user', 'created')

或者您可以在表单上使用clean方法来检查:

class NewBeerForm(forms.ModelForm):
    ...
    def clean(self):
        cleaned_data = super().clean() 
        user = cleaned_data.get('user')
        created = datetime.now().date()           
        if BeerModel.objects.filter(user=user, created=created).exists():
            raise forms.ValidationError("User already created beer today")

你可能总是需要clean,因为我上面提到的票证(如果它仍然适用)。如果对日期使用可编辑字段,则必须确保将当前日期保存到数据库中。 E.g:

if beer.is_valid():
    instance = beer.save(commit=False)
    instance.created = datetime.now().date()
    instance.save()